Category : Html | Author : Chtiwi Malek | First posted : 12/30/2012 | Updated : 4/10/2013
Tags : canvas, undo, redo, html5, tutorial, draw, erase, paint, rewind, code, script
Undo and Redo with HTML5 Canvas

Undo and Redo with HTML5 Canvas

Some time ago, I wrote a tutorial explaining how to draw on a html5 canvas with the mouse, in this tutorial I will add a simple undo and redo functions to the canvas.

Live running example :



  Line width : Color :       

How it is done ?

To implement undo/redo feature for the canvas I decided to store a snapshot from the canvas (using the canvas’s toDataURL method) to an array "cPushArray", so each time the user draw or add something to the canvas the function cPush is called.

If cPush is called and the current position is not the last one, the array will be resized and all the following records will be deleted :
var cPushArray = new Array();
var cStep = -1;
var ctx;
// ctx = document.getElementById('myCanvas').getContext("2d");
	
function cPush() {
    cStep++;
    if (cStep < cPushArray.length) { cPushArray.length = cStep; }
    cPushArray.push(document.getElementById('myCanvas').toDataURL());
}
When the user clicks the Undo button, the function cUndo will load and display the previous state using the drawImage method :
function cUndo() {
    if (cStep > 0) {
        cStep--;
        var canvasPic = new Image();
        canvasPic.src = cPushArray[cStep];
        canvasPic.onload = function () { ctx.drawImage(canvasPic, 0, 0); }
    }
}
When the user clicks the Redo button, the function cRedo will load and display the next available state in the cPushArray using the drawImage method :
function cRedo() {
    if (cStep < cPushArray.length-1) {
        cStep++;
        var canvasPic = new Image();
        canvasPic.src = cPushArray[cStep];
        canvasPic.onload = function () { ctx.drawImage(canvasPic, 0, 0); }
    }
}
This method is simple and straightforward, but if you are using an object-based canvas drawing you'll need a more complex approach to keep track of all the objects, positions, seizes ...

A full running sample and source code is available in the zip file attached to this article.

Happy coding and Feel free to make comments or ask questions.
About the author :
Malek Chtiwi is the man behind Codicode.com
34 years old full stack developer.
Loves technology; but also likes design, photography and composing music.
Comments & Opinions :
RKJ
It works like charm. thank you very much.
- by RItesh on 2/1/2013
Create stand-along page for each code
Hi,
Wonderfull work. Thank you.
I have a suggestion if you can please add stand-along page for each code so people can visit that page see the example and copy the code with any extra stuff.

thanks

- by Ahmad Jamal on 11/8/2013
Background color and image
How to undo and redo background color and image of object in javascript
- by Rajeev Rahi on 3/31/2016
i also need a same thing 
- by yash thakur on 12/4/2017
Web-developer and consultant
Thanks a lot! However in my project I had to generate canvas again before the back function worked because canvas is transparent!
- by Niki Ahlskog on 11/21/2016
mr
erasing is simple as u just take advantage of the white colour
- by kipsang on 3/13/2017
It will work, but careful when using this approach:
As I said, it will work. But saving the whole canvas as ana image for undo or redo, is memory intensive, and a performance killer. 
A better approach can be saving an array containing the "history" of the user draw. Like {fromX: number, toX: number, fromY: number, toY: number}. In this way you just cycle over the array redrawing each point except the last one, that was popped out before the redraw. Here's the stack overflow post talking about this: https://stackoverflow.com/questions/17150610/undo-redo-for-paint-program-canvas
- by Max on 12/20/2017
Need touch screen writing too
I want to also have touch-screen writing can you help? Thanks 
- by Unxi on 5/21/2020
issue
Doesn't work without using an actual image  
When I try to undo the drawing without loading .jpg image initialy, it's not working!
- by arya on 10/26/2020
Leave a Comment:
Name :
Email : * will not be shown
Title :
Comment :