How to create Undo-Redo in kineticjs?

后端 未结 4 1839
误落风尘
误落风尘 2020-12-21 16:13

Is there any simple way how to create undo redo function in Kineticjs ? I have found a Undo Manager for HTML 5 in https://github.com/ArthurClemens/Javascri

相关标签:
4条回答
  • 2020-12-21 16:55

    i have written a class for the functionality: http://www.sebastianviereck.de/en/redo-undo-class-kinetic-js/

    0 讨论(0)
  • 2020-12-21 16:56

    To solve event listeners problem, work on by making clones

    $scope.makeHistory=function() { 
      $scope.historyStep++;
      if ($scope.historyStep < $scope.history.length) {
          $scope.history.length = $scope.historyStep;
      } 
      var layerC = $scope.topLayer.clone(); 
      $scope.history.push(layerC);   
    };
    
     $scope.undoObject = function(){  
      if($scope.historyStep > 0) {
        $scope.historyStep--;
        $scope.topLayer.destroy(); 
        if($scope.historyStep==0){
          $scope.topLayerAdd(2); // will put empty layer
        }
        else{
          var layer = $scope.history[$scope.historyStep-1].clone();
          $scope.topLayerAdd(1,layer);
        } 
        $scope.topLayer.draw();
      } 
    };
    
    $scope.redoObject = function(){  
      if($scope.historyStep <= $scope.history.length-1) {  
        $scope.historyStep++;
        $scope.topLayer.destroy();  
        var layer = $scope.history[$scope.historyStep-1].clone(); 
        if($scope.historyStep==0){
          $scope.topLayerAdd(2);   // will put empty layer
        }
        else{
          $scope.topLayerAdd(1,layer); 
        } 
        $scope.topLayer.draw();  
      } 
    };
    

    works perfectly for me.

    0 讨论(0)
  • 2020-12-21 17:03

    I was able to implement a simple solution based on a post by Chtiwi Malek at CodiCode. I also used some of the code from this problem as an example to draw rectangles, so credits go to them and Chtiwi.

    The only difference in my solution is I used toJSON() to store each layer state in an array instead of toDataURL() on the canvas. I think toJSON() is needed over toDataURL() to be able to serialize all the data necessary to store each action on the canvas, but I'm not 100% on this so if someone else knows please leave a comment.

    function makeHistory() {
        historyStep++;
        if (historyStep < history.length) {
            history.length = historyStep;
        }
        json = layer.toJSON();
        history.push(json);
    }
    

    Call this function everytime you want to save a step to undo or redo. In my case, I call this function on every mouseup event.

    Bind these 2 functions to the Undo/Redo events.

    function undoHistory() {
        if (historyStep > 0) {
            historyStep--;
            layer.destroy();
            layer = Kinetic.Node.create(history[historyStep], 'container')
            stage.add(layer);
        }
    }
    
    function redoHistory() {
        if (historyStep < history.length-1) {
            historyStep++;
            layer.destroy();
            layer = Kinetic.Node.create(history[historyStep], 'container')
            stage.add(layer);
        }
    }
    

    Here's the jsfiddle. Don't forget to initialize the array and step counter up top. Good luck!

    0 讨论(0)
  • 2020-12-21 17:13

    I am not familiar with KineticJS, but the approach should be similar to the provided demo (that also uses a canvas).

    Perhaps another example helps. Let's say I have an app to create/move/delete colored shapes that represent musical notes. I have a way to click-drag and highlight a selection of notes. Pressing Delete on the keyboard invokes the function onDeleteGroup:

    onDeleteGroup: function(gridModel) {
        // collect all notes in an array
        // ...
        this._deleteGroup(notes);
        this.undoManager.register(
            this, this._createGroup, [notes], 'Undo delete',
            this, this._deleteGroup, [notes], 'Redo delete'
        );
    }
    

    All notes are deleted, and 2 methods are registered with the undo manager:

    1. The undo function (undo of delete will be create)
    2. The redo function (after undo/create will be delete again)

    Both functions are straightforward:

    _deleteGroup:function(notes) {
        // removes each note from the model
        // thereby removing them from the canvas
        // ...
    }
    
    _createGroup:function(notes) {
        // add each note to the model
        // thereby adding them to the canvas
        // ...
    }
    

    As you can see, the data object (array of notes) is passed around for creation and deleting. You can do the same for manipulating singular objects.

    0 讨论(0)
提交回复
热议问题