4

I'm trying to implement an undo-function for a canvas. Basically people can draw on a canvas, and then restore it to the state it was before. That's the theory. I save the current imageData every time I call a function draw. It's saved in an array eD(namespace).history. Drawing works fine, even if I manipulate the imageData. Here's my draw-function (cD is a namespace aswell):

editorClass.prototype.draw = function(){
    eD.history.push(cD.imageData);
    cD.context.putImageData(cD.imageData, 0, 0);
}

Now if I try to undo my changes I've made in between, I use a function called undo, which looks like that:

editorClass.prototype.undo = function(){
    var temp = eD.history.pop();
    cD.context.createImageData(cD.width,cD.height); //Can leave this out, nothing changes
    cD.context.putImageData(temp, 0, 0);
}

As mentioned above, that won't work. The canvas I work with is created once the user loads the site. cD.imageData originates from this function:

editorClass.prototype.getPixels = function(){
    cD.imageData = cD.context.getImageData(0, 0, cD.width, cD.height);
    // get the image data of the context and save them into namespace
    cD.pixels = cD.imageData.data;
    // get the pixels

    cD.pixelsLength = cD.width * cD.height * 4;
    // precompute the length of the pixel array
}

Both namespaces are visible, if needed. Since I'm pretty new to canvas, it might be a simple question - so if you have improvements: I'm an empty bucked, fill me in ;)

Thanks

1 Answer 1

3

Without seeing all the code I'm not sure exactly why yours isn't working but I suspect its due to only trying to do a putImageData with the pixel array and not the image data object.

Heres a demo I wrote that works

Live Demo

And here is the relevant Code

var savedData = [];   

undoButt.addEventListener("click", function () {
    // as long as there is data put it onto the canvas.
    if (savedData.length > 0) {
        var imgData = savedData.pop();
        drawCtx.putImageData(imgData, 0, 0);
    }
});

drawCanvas.addEventListener("mousedown", function (e) {
    // push the current state
    var imgData = drawCtx.getImageData(0, 0, drawCanvas.width, drawCanvas.height);
    savedData.push(imgData);

});

Its the same concept you used, it seems to work alright.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi,thanks you've helped me more than you might think. It's actually working now. When I refactored my code yesterday I thought that I'm doing something wrong regarding the canvas handling. Seeing you're code I realized, that mine was alright. It was rather a mistake in the logic. I was saving the imageData when I drew the canvas, so after the imageData already was manipulated. All I had to do is to save the imageData not after but before it was manipulated - It was pretty late yesterday ;) Anyway, thanks that's it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.