helloworld
helloworld

Reputation: 1042

Undo/ redo functionality in html canvas

I am working on html canvas . I have implemented following features:

1) Simple Draw
2) Erasor
3) Shapes Draw
4) Shapes Resize
5) Shapes Move
6) Color Select

Now, I want to add undo/redo functionality.

Considering the above features implemented, I am thinking saving instance of entire canvas on every event execution. For example, on doing a shape resize, I push the entire canvas instance into an array.

When user clicks on undo, I simply, pop the last element from array, and repaint the canvas.

But, I am thinking saving the entire canvas instance everytime will be memory intensive and also not very optimal performance wise. Also, with this approach, I will have to limit the maximum number of undo/redo allowed. What would be the ideal number of undo/redo should I keep if I go ahead with this approach. Also, is there a better approach for this considering the above features.

Upvotes: 0

Views: 647

Answers (2)

Steven Spungin
Steven Spungin

Reputation: 29109

Use the command design pattern, and redraw your canvas from your history of commands. You will be able to save a large amount of steps (hundreds if not thousands).

In a nutshell, instead of drawing to canvas directly, you will wrap your operation in a command that is added to a list, and then executed. When the user wants to undo, you remove the last operation from the list, and replay it. You can also keep the list intact and update an index marker to allow for redo.

In your case, you would also have commands for tool selection, so the selections would also be 'recorded' into your history.

Once you start using this pattern, you may find your entire application would be better structured using a state object, wrapped in a store that uses commit operations for all access. Then you get the undo-redo for free. See redux, vuex, and flux for the de facto standards of this store design. As powerful as these libraries are, they are really lean and quite simple.

https://en.wikipedia.org/wiki/Command_pattern

Upvotes: 3

Simmetric
Simmetric

Reputation: 1661

An alternative to the command pattern is the Memento pattern where you simply store the current state of the canvas every time an action is done. This requires more memory and generally will need to be restricted to small number of edits. Restoring an earlier state should be pretty fast though.

Upvotes: 1

Related Questions