Pergunta

I am in the middle of development of a designer drawing tool using Canvas HTML5. I will have features like: add image, add text, add shape, rotate, scale, color, etc...

I was in search of a nice way to manage action history (undo, redo) and I have found a very nice approach, you can find it here: How to do undo redo

I was very happy that it will make my life easier than I thought, but I was wrong. It is based on Kinetic.Node.create('json', jsonLayer); . Though it seemed to work fine for the first sight, it has some problems:

  • it looses reference to layer after remove layer and create new instead
  • it looses all the image inside layer
  • and the biggsest problem is that it looses event handlers inside layer, which I have many

What other possibilities could you recommend to me? I was thinking about the following:

  • save the operations in an array and on undo I would do the reverse of them programatically
  • serialize and store in an array each children of the layer, then on undo I would rebuild the layer (looks too complex)
Foi útil?

Solução

Yes, a Kinetic save to JSON will not include either event handlers or images.

You must rewire the handlers after the JSON nodes have been deserialized and rehydrated.

With some preparation, you can even automate this rewiring.

For example,

First save all your event handlers in an object or array:

var eventHandlers={
    myClickHandler1:function(e){ alert("Fired myClickHandler1"); },
    myClickHandler2:function(e){ alert("Fired myClickHandler2"); },
    myMouseMoveHandler1:function(e){ alert("Fired myMouseMoveHandler1"); },
    myMouseMoveHandler2:function(e){ alert("Fired mymouseMoveHandler2"); }
}

Second add a custom attribute to each Kinetic.Node that needs an event handler:

var circle1 = new Kinetic.Circle({
    x:100,
    y:100,
    radius: 30,
    fill: 'red',
    stroke: 'black',
    strokeWidth: 4,
    draggable: true,
    clickEvent:"myClickHandler1"
});

Finally after the node has been rehydrated you can automatically rewire the event handlers:

function rewireHandlers(node){

    var handler;

    // rewire click handler
    handler=node.getAttr("clickEvent");
    if(handler && eventHandlers[handler]){
        node.on("click",eventHandlers[handler])
    }

    // rewire other event handlers the same way
}

// call for rewiring 
rewireHandlers(circle1);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top