Tuesday, 29 July 2014

Building a drawing app with HTML5's canvas (Part 6)


In this part of the tutorial series, we complete our canvas drawing app by adding a save button to our control bar on top that will let the user save the image to their disk.

Initially I thought about making it such that we can store the image on our servers but then I decided not to get into the server side part of it as we've always focused on the front-end...

We can now save our masterpieces with the save button to the left of our colour palette...
We can now save our masterpieces with the save button to the left of our colour palette...
View Code View Demo

Saving our images to disk- The Theory

Now, let's talk about how we'll save our images to the disk. Well, with HTML 4.01 it was really difficult. You'd have to create a server script that would store the image on the server and then return some data URL that would have a content-disposition header set to attachment and bla bla bla...

But with HTML5 it's a piece of cake to download our canvas image to the disk. With HTML5, the anchor tag has an attribute called "download". This attribute takes in a file name and when the link is clicked the resultant page would be downloaded to the users' disk.

So, in our code, we'll first create a save button which would technically be an anchor tag:
<a id="save">Save</a>
You can style it however you want but if you've been following me along the tutorials and want to use the same styles you can just click on "View Code" above and use the styles that I've used...

When the button is clicked (I know that it's an anchor tag but I've styled it so that it looks like a button), we want to call a function that would set the href attribute of the anchor tag and the download attribute of the anchor tag so that the href target gets downloaded..

Now, you might ask, "What will our href be?", well, the simple answer is, "A URL that contains the image". How do we generate such URLs on the fly? Well, really, we don't have to, canvas does it for us using the toDataURL method...

Generating data URLs for our image using canvas' toDataURL method

HTML5's canvas has a method called toDataURL that returns a URL that might look somewhat like this:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAMHCAYAAADPafCkAAAgAElEQ…ABAgQIEBCgfYAAAQIECBAgQIAAAQIECBAgQIAAAQIEFoEAfkgDCAJydSgAAAAASUVORK5CYII="
We don't have to understand what it really means, all we have to know is that it's a URL just like http://www.stronia.com... So, we can have anchor tags point to such URLs using the href attribute.

To download the images all we have to do is set the download attribute of the anchor tag to some filename and so when the link is clicked the image is saved onto your disk...

For example:
<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAMHCAYAAADPafCkAAAgAElEQ%E2%80%A6AAAQIPAQf0Q10mAQIECBAgQIAAAQIECBAgQIAAAQIEAgIDxFeVcc78NDoAAAAASUVORK5CYII=" download="some_file_name.png">Download this image</a>

Applying this knowledge to our canvas app

So, recall that we gave our save button (an anchor) the id of "save." So, we'll reference the element from our JavaScript and attach a click event listener to it...
var saveButton = document.getElementById("save");
saveButton.addEventListener("click", saveImage);
So, all we're doing with the code above is telling the browser to call the function called saveImage when the save button is clicked...

Now, what should our saveImage function do? Well, all it has to do, is set the anchor tag's href attribute to the data URL and set the download attribute to some file_name.
var saveImage = function(e){
    save.href = canvas.toDataURL();
    save.download = 'canvas_output';
}
This will save the image as "canvas_output.png" on the user's disk...

But there's a problem, it the user want's to cancel the download after the save button has been clicked it's impossible. Also, we might want to let our user select the file name instead of us forcing them to use what we want them to...

So, let's have a prompt dialog to take in a filename from the user. Also as JavaScript's prompt dialogs work, if they click "cancel", we'll get back an empty string, so we wont save the file...
var saveImage = function(e){
    var filename = prompt("Choose a filename for your image:");
    if (filename){
        save.href = canvas.toDataURL();
        save.download = filename;
    }
}

The End

So, we've learnt through the parts of this series to build a drawing application. We can change the brush size, colour and also save our masterpieces to the disk.

Please share your thoughts with me using the comments below and please recommend this to your friends if you enjoyed it..

Thank you for sticking with me till the end of this series!

No comments:

Post a Comment