2

I'm trying to build in a change history, rather than a diff style history, I've opted to save the entire object. This becomes problematic because each copy of the object updates along side the original object.

The Kinetic.Node.clone method seemed like the right thing for me, but it doesn't seem to do what I expect it to do.

Pseudocode:

var History = function(){
  var h = this;
  h.history = [];
  h.pointer = -1;
  h.save = function() {
    h.history = h.history.slice(0,h.pointer);
    h.history.push(im.Stage.createCopy());
    h.movePointer(1);
  };
  h.movePointer = function(diff) {
    h.pointer += diff;
    (h.pointer < 0 && (h.pointer = 0));
    (h.pointer >= h.history.length && (h.pointer = h.history.length-1));
    return h.pointer;
  };
  h.render = function() {
    im.Stage = h.history[h.pointer].createCopy();
    im.Stage.draw();
  };
  h.undo = function() {
    h.movePointer(-1);
    h.render();
  };
  h.redo = function() {
    h.movePointer(1);
    h.render();
  };
};

How can I create an accurate copy of the stage?

Korvin Szanto
  • 4,531
  • 4
  • 19
  • 49
  • IIRC, clone doesn't work very well because the underlying reference stays the same, this was an issue for me too. If you're trying to clone the entire stage, why can't you use toImage? – michael.orchard Nov 02 '12 at 16:48
  • @mickylaaaad The problem with simply outputting to an image is that it doesn't store the current state, it just stores a rendered version of the canvases. The issue with clone seems to be known and in the process of being fixed, but even with a working version, it's incredibly slow to save the stage on each change. To attempt to speed it up, I've started saving an array of the layers, but this is still rather inefficient. – Korvin Szanto Nov 02 '12 at 17:59

2 Answers2

0

The best thing for an accurate representation is to do:

 var layers = stage.getChildren();

to get the layers. Then do:

 var layerChildren = new Array();
 for(var i=0; i<layers.length; i++)
    layerChildren[i] = layers.getChildren();

each time you want to save a state.

This will store all your layers and their children in an array. Fairly efficient and accurate.

Now you just have to save the list of layers and list of children somewhere and then you can move back and forth between states.

SoluableNonagon
  • 11,541
  • 11
  • 53
  • 98
0

The best method to build up a history system is to store your layers/elements after each operation into an array as serialized values, using layer.toJSON() .
If you use images on layers and eventhandlers that you want to display/work after you restore anything from the history then you will have to reattache images and eventhandlers to the objects/layers/etc because toJSON() does not store images and eventhandlers as it would have been too large data stored. Build up your history like this:

  1. first, try to use projeqht's answer on this question .
  2. second you will have to reattach the images and eventhandlers. With a trick given by markE on this question you can easily handle it.
Community
  • 1
  • 1
Ervin
  • 2,374
  • 4
  • 30
  • 44