Up until now, we've worked with storing text values in LocalStorage
. I hope you agree that it is an easy process to perform, and that used with care, we can achieve some great results. I mentioned though, at the end of the last recipe, that we could really turn the tables, and start to store images in LocalStorage
. We'll see how to achieve this, using a technique developed by Rob Nyman, a Technical Evangelist at Mozilla.
For this recipe, we will need a suitable image to store in LocalStorage
. There is no hard and fast rule on size, but we should bear in mind that in reality LocalStorage
can't hold more than 5 to 10 MB (depending on the browser), so it is wise to choose a sensible size. I will assume you have selected a suitable image, which is ideally 250px
in width and 377px
in height, so as to avoid the need to alter the CSS styling used in this recipe.
You will also need a copy of the code that is available with this book, and of course your trusty text editor, as always!
Perform the following steps, for storing images within LocalStorage
:
image
in localstorage
, and save this on your hard disk. Inside this folder, create two subfolders called js
and css
.lsimage.html
file from image
in the localstorage
folder, and save it in the folder we've just created.base.js
, in the js
subfolder. We'll go through it block by block, starting with declaring a number of variables:(function () { // localStorage with image var storageFiles = JSON.parse(localStorage.getItem("storageFiles")) || {}, elephant = document.getElementById("elephant"), storageFilesDate = storageFiles.date, date = new Date(), todaysDate = (date.getMonth() + 1).toString() + date.getDate().toString();
LocalStorage
area exists already; if not, go ahead and create a new one, set up the canvas element, and draw the image on it:if (typeof storageFilesDate === "undefined" || storageFilesDate < todaysDate) { elephant.addEventListener("load", function () { var imgCanvas = document.createElement("canvas"); var imgContext = imgCanvas.getContext("2d"); imgCanvas.width = elephant.width; imgCanvas.height = elephant.height; imgContext.drawImage(elephant, 0, 0, elephant.width, elephant.height);
LocalStorage
:storageFiles.elephant = imgCanvas.toDataURL("image/png"); storageFiles.date = todaysDate; try { localStorage.setItem("storageFiles", JSON.stringify(storageFiles)); } catch (e) { console.log("Storage failed: " + e); } }, false); elephant.setAttribute("src", "elephant.png"); }
LocalStorage
:else { elephant.setAttribute("src", storageFiles.elephant); } })();
base.css
, stored in the css
subfolder:body { font: 12px "Helvetica Neue", "Helvetica", sans-serif; background: #ccc; } h1 { margin-top: 0; } img { padding: 10px; box-shadow: 0 0 10px 2px #ccc; margin-bottom: 5px; } figcaption { font-style: italic; } header { margin-bottom: 20px; border-bottom: 1px solid #000; } .container { width: 675px; background: #fff; border-radius: 10px; margin: 0 auto; padding: 30px; } .main-content { overflow: hidden; } .additional-content { float: right; width: 300px; height: 110px; padding: 10px; background: #ccc; border-radius: 5px } .page-footer { border-top: 1px solid #000; margin-top: 30px; padding-top: 10px; }
In this recipe, the code of particular interest is in the base.js
file we've created for this demo. We start by checking to if our LocalStorage
element is already present. If so, the code uses the image directly from LocalStorage
, otherwise it sets up a number of variables for storing values such as the date on which the image was stored, today's date, and of course the image is converted to a string using JSON.
We then do a check to confirm dates and create LocalStorage
based on the outcome. If all is well, we can go ahead with first creating a canvas element and then drawing the full image on the canvas. We save a copy of the image as a data URL, and set the date. It is then converted to a string using JSON and finally stored (provided it is not too big).
This is a very powerful method, but that should be used with care. Local Storage was not designed to handle huge images! This said, it will be very useful, particularly for images that rarely change, such as navigation buttons or company logos. A good method to use would be converting any images into sprites. This could help reduce the number of different requests required, and potentially the size of the file being held.
A number of developers have taken this principle a step further, and created cache plugins for storing images in LocalStorage
. Visit http://www.jquery4u.com/plugins/10-jquery-image-cache-plugins-scripts/ if you would like to explore this functionality further.
Okay, before moving onto looking at our next demonstration, there is one area we must take a look at, and upon which I am sure you will ask questions. It relates to the amount of storage area available within LocalStorage
, as we will see in the next recipe.