I have a specific problem on my designer drawing tool in Canvas HTML5. I am developing an action history system (Undo & Redo). I am building my system on projeqht's answer on this question with serializing the layers in history array. The core, the idea of the solution is working but I have a strange problem. When I hit Undo it creates the new layers, but the old ones are not disappearing. I will attach my sourcecode and I will attach screenshots as well so you can see what is happening:
Sourcecode:
var history = Array(null);
var historyStep = 0;
var arrayNonRemovable = Array('moveLayer', 'scaleFromOuterNode', 'scaleFromInnerNode', 'rotateFromOuterSign', 'rotateFromInnerSign' );
function removeLayerByUndoRedo(l) { if (l) { l.destroy(); l.draw(); stage.draw(); } }
function makeHistory(layer, before, after, operation) { historyStep++; if (historyStep
function undoHistory() { if (historyStep>0) { version = history[historyStep]; layer = version.layer; var beforeState = history[historyStep].before;
removeLayerByUndoRedo(layer);
var layer = Kinetic.Node.create(beforeState, 'container');
stage.add(layer);
stage.draw();
historyStep--;
}
}
Array.prototype.contains = function(obj) { return this.indexOf(obj) > -1; };
Screenshots: Step 1. create the object, which contains more groups with shapes inside (lines, rectangles, SVG drawing) Steps 2, 3, 4, 5: Moving object to different positions (top left, bottom left, bottom right and top right): Step 6: Press Undo for first time (removes the old layer well and recreates it from history well): Step 7: Press Undo for second time (creates new layer from history, but old layer is not removed) Step 8, 9: Press Undo for another 2 times (same happens as in Step 7: creates new layer but old ones remain):
Am I doing something wrong? I think it must be something with the reference to the new layers as in Step 6 the removed layers reference is the original layer, in the following steps those are new layers, so reference should be a new one?
Here's what the probloem was: I store the layer reference in the history array. So when I create an object the layer reference is stored in history[1]. I move it to 3 times, I will have the same reference in the history for all the steps. When I press undo, I am destroying the layer calling it from the stored reference and I create a new one which reference is a new one. In the history I still have the old reference, which points to NULL. This was the problem.
I have fixed it destroying the old layer calling it by name. (This only works if you give unique names to layers):
stage.find('.'+layer.getName())[0].destroy()
After you serialize the layer to JSON, you must do
Your code seems to do this so I would need more code to find what's going wrong.
A long-shot possibility:
I see that your undoHistory references a global
layer
and also creates a locallayer
. Try refactoring your code like this to be sure you're not mixing different "layer":You don't need to do l.draw() or stage.draw() after l.destroy() because the layer is being destroyed anyway and the stage is auto-updated when the layer is destroyed.
Here is a working example of layer.destroy that may help until you can post more code:
http://jsfiddle.net/m1erickson/FSBbN/