Tutorials‎ > ‎

Using Web Storage to save Canvas data

posted Dec 23, 2011, 2:34 AM by Sofia _   [ updated Aug 15, 2016, 11:39 PM by Surya Wang ]

Web Storage

Web Storage and DOM Storage (Document Object Model) are web application software methods and protocols used for storing data in a web browser. Web storage supports persistent data storage, similar to cookies, as well as window-local storage.

Web storage is being standardized by the World Wide Web Consortium (W3C). It was originally part of the HTML 5 specification, but is now in a separate specification. It is supported by Internet Explorer 8, Mozilla-based browsers (e.g., Firefox 2+, officially from 3.5),Safari 4, Google Chrome 4 (sessionStorage is from 5), and Opera 10.50. As of 14 July 2010 only Opera supports the storage events. (Source)

HTML5 offers two new objects for storing data on the client:
  1. localStorage - stores data with no time limit
  2. sessionStorage - stores data for one session

Earlier, this was done with cookies. Cookies are not suitable for large amounts of data, because they are passed on by EVERY request to the server, making it very slow and in-effective.In HTML5, the data is NOT passed on by every server request, but used ONLY when asked for. It is possible to store large amounts of data without affecting the website's performance.

The data is stored in different areas for different websites, and a website can only access data stored by itself. HTML5 uses JavaScript to store and access the data. (Source)

The data will not be lost even you close the page or even your browser. There's simple example using localStorage :

<script type="text/javascript">
//to store the data
localStorage.myData = "Hello kitty";
//to read the data
document.write(localStorage.myData);
</script>


If you want to store it for one session just simply change "localStorage" to "sessionStorage". The session storage's data will be deleted when the browser closed. Here is another example of web storage. I am using web storage to store an array of json data.
<script>
var shapes =  new Array();
shapes[0] =  {"x" : 1 , "y" : 2};
shapes[1] =  {"x" : 3 , "y" : 4};
//store the data
localStorage["tes"] = JSON.stringify(shapes);
 
//read the data
var store = JSON.parse(localStorage["tes"]);
document.write(store[0].x + " " + store[0].y + "<br/>");
document.write(store[1].x + " " + store[1].y + "<br/>");
</script>


Note : If you test the web storage in local using file:///. It will not work, you need to test it in server such as localhost

Canvas

Canvas is one of the feature you can find in html5. It’s allow us to draw in the area called canvas to create a canvas simple add a canvas tag in anywhere you want and draw on it using javasript. Here is a simple example to draw rectangle in canvas

<canvas id="myCanvas" style="border:1px black solid;" width="200px" height="200px">
    Your browser doesn't support canvas.
</canvas>
<script>
    //get the canvas element
    var myCanvas = document.getElementById("myCanvas");
    //get the context from canvas to draw
    var myContext = myCanvas.getContext("2d");
    //adjust the shadow blur and its color
    myContext.shadowBlur = 10;
    myContext.shadowColor = "black";
    //adjust the border of the rectangle
    myContext.lineWidth = 10;
    myContext.strokeStyle = "#FAF";
    myContext.strokeRect (10,10,100,100);
    //draw rectangle and its fill color
    myContext.fillStyle = "#000";
    myContext.fillRect (10,10,100,100);
</script>

Using web storage to save canvas data

Using canvas and web storage example above is enough for us to do many thing. I create a simple example to store my coordinat and color etc to draw in canvas to localStorage so it’s allowed us to open the graphic we save anytime we want. First, in the body part. Create a canvas, some button to allow user to choose the color and shadow effect. Don’t forget to add button to create a new page, save page, and open the page already save. Here is the result :

For the script, just use your logic and imagination from the example above. I am using Jquery to make it easier.
 //the variable we need to use
var color = "#FFF";
    var strokeColor = "#000";
    var canvasW = 600;
    var canvasH = 300;
    var isDraw = false;
    var shapes =  new Array();
    var fileNames = new Array();
    var totalShapes = 1;
 
    //what to do in the beginning
    $(function() {
        //check if there is data already store, if it is true just add the option to the select
        if(localStorage.fileNames)
        {
            fileNames = JSON.parse(localStorage.fileNames);
            for(var k=0;k<fileNames.length;k++)
                $("#fileNamesControl").append("<option>" +fileNames[k]+ "</option>");
        }
 
        //setting the default color, canvas offset and line width
        $("#myRect").css("border-color",strokeColor);
        $("#myRect").css("background-color",color);
 
        canvas = $("#myCanvas").offset();
        lineWidth = 5;
 
        //what to do if the mouse is move in the canvas
        $("#myCanvas").mousemove(function(e) {
            if (isDraw) {
                endX = e.pageX - canvas.left;
                endY = e.pageY - canvas.top;
                totalShapes = totalShapes - 1;
                addShape();
                draw();
            }
        });
 
        //what to do if the mouseup event occured in canvas
        $("#myCanvas").mouseup(function(e) {
            isDraw = false;
            addShape();
        });
 
        //what to do if the mousedown in canvas
        $("#myCanvas").mousedown(function(e) {
            isDraw = true;
            beginX = e.pageX;
            beginY = e.pageY;
        });
 
        //when the mousedown occured in class color
        //change the color according to the button
        $(".color").mousedown(function(e){
            if(e.which == 1)
                color = $(this).css("background-color");
            else if(e.which == 3)
                strokeColor = $(this).css("background-color");
            $("#myRect").css("background-color",color);
            $("#myRect").css("border-color",strokeColor);
        });
 
        //clear everything when the “newPage” is pressed
        $("#newPage").click(function(){
            totalShapes = 1;
            myContext.clearRect(0,0,canvasW,canvasH);
        });
 
        //what to do when save button is clicked
        $("#save").click(function(){
            var fileName = prompt("Please fill name","");
            if(fileName.length != 0)
            {
                if($.inArray(fileName,fileNames) != -1)
                    alert("File name already exists");
                else
                {
                    localStorage[fileName] = JSON.stringify(shapes);
                    fileNames[fileNames.length] = fileName;
                    localStorage.fileNames = JSON.stringify(fileNames);
                    $("#fileNamesControl").append("<option>" +fileName+ "</option>");
                }
            }
            else alert("Please fill page name");
        });
 
        //what to do when the open button is clicked
        $("#open").click(function(){
            var com = $("#fileNamesControl").val();
            if(com != null){
                shapes = JSON.parse(localStorage[com]);
                totalShapes = shapes.length;
                draw();
            }
        });
    });

Here is my function to addShape to shapes. I am using json to store it, because it’s easier to use.
function addShape()
{
    shapes[totalShapes] = {
        "x1" : beginX,
        "y1" : beginY,
        "x2" : endX,
        "y2" : endY,
        "shadow" : $("#myShadow").attr("checked"),
        "strokeColor" : strokeColor,
        "color" : color
    };
    totalShapes += 1;
}


Here is my draw function. Just looping the shapes and then draw rectangle according to it’s attribute.
function draw() {
    myCanvas = document.getElementById("myCanvas");
    myContext = myCanvas.getContext("2d");
    myContext.clearRect(0,0,canvasW,canvasH);
    for(var j=0;j<totalShapes;j++)
    {
        var temp = shapes[j];
        if(temp.shadow){
            myContext.shadowBlur = 10;
            myContext.shadowColor = "black";
        }
        else
        {
            myContext.shadowBlur = 0;
        }
        myContext.lineWidth = 5;
        myContext.strokeStyle = temp.strokeColor;
        myContext.strokeRect (temp.x1, temp.y1, temp.x2-temp.x1, temp.y2-temp.y1);
        myContext.fillStyle = temp.color;
        myContext.fillRect (temp.x1, temp.y1, temp.x2-temp.x1, temp.y2-temp.y1);
    }
}


ċ
WebStorageAndCanvas.zip
(2k)
Sofia _,
Dec 23, 2011, 2:51 AM