Saving HTML5 canvas as image
How to save your <canvas> as an image in javascript
Pic by Paurian

Canvas is a powerful drawing technology for the web. One of its biggest caveats is that it's not easy to save the canvas image data to your computer. In this post, I'll show two ways that will allow your users to save what they see in their browser to their desktop.

Right-click to save

First thing I try when I want to save something I see in my browser, is right clicking it and looking for Save as... All browsers treat <canvas> the way they treat a <div>, so that's not an option. However, an <img> has an option to save in its context menu.

Start off with creating an image and overlapping it on top of the canvas (note that this will block all user interaction events on the canvas, so you'll have to pass them through manually).

<div class="canvas__container">
  <canvas id="cnvs" class="canvas__canvas"></canvas>
  <img src="" id="mirror" class="canvas__mirror" />
</div>

Add some basic styling to put them on top of eachother.

.canvas__container {
  height: 100%;
  position: relative;
  width: 100%;
}
.canvas__canvas {
  height: 100%;
  position: relative;
  width: 100%;
  z-index: 1;
}
.canvas__mirror {
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%; 
}

And don't forget to set the canvas width and height with Javascript.

var cnvs = document.getElementById('cnvs'),
    ctx = cnvs.getContext('2d'),
    mirror = document.getElementById('mirror');

cnvs.width = mirror.width = window.innerWidth; cnvs.height = mirror.height = window.innerHeight;

That's basic HTML5 canvas setup, nothing new. Next is to bind an event listener to a right click on img#mirror.

mirror.addEventListener('contextmenu', function (e) { });

In this function, we'll parse the canvas to a data URL and set it as the image src. When the user chooses Save as in the context menu, the browser will show a file dialog, allowing the user to save the canvas visual to his computer.

mirror.addEventListener('contextmenu', function (e) {
    var dataURL = canvas.toDataURL('image/png');
    mirror.src = dataURL;
});

That's it! Now, let's say you want a visual download button.

Download button

Let's take this principle of parsing the canvas to a data URL and apply it to a download button.

Start off with creating a basic <a>.

<a href="#" class="button" id="btn-download">Download</a>

All you need to do is listen to the click instead of the context menu in the previous example:

var button = document.getElementById('btn-download');
button.addEventListener('click', function (e) {
    var dataURL = canvas.toDataURL('image/png');
    button.href = dataURL;
});

Running this results in a button that opens the canvas image in the browser window. Forcing download on the front-end side using the download attribute is a relatively young feature, supported only by Chrome and Firefox. It's better than nothing. You could try a cross-browser solution using a server-side file processor and AJAX, but I won't cover that in this post.

<a href="#" class="button" id="btn-download" download="my-file-name.png">Download</a>

That's it! Remember that if you don't explicitly draw a background, it'll be a transparent PNG. Have fun drawing!

Written by Pieter Beulque