Undo-Redo feature in Fabric.js

前端 未结 9 731
梦谈多话
梦谈多话 2020-12-04 13:28

Is there any built-in support for for undo/redo in Fabric.js? Can you please guide me on how you used this cancel and repeat in [http://printio.ru/][1]

相关标签:
9条回答
  • 2020-12-04 14:10

    i developed a small script for you,hope it will help you .see this demo Fiddle although redo is not perfect you have to click minimum two time at undo button then redo work .you can easily solve this problem with giving simple conditions in redo code. //Html

    <canvas id="c" width="400" height="200" style=" border-radius:25px 25px 25px 25px"></canvas>
      <br>
       <br>
     <input type="button" id="addtext" value="Add Text"/>
    <input type="button" id="undo" value="Undo"/>
    <input type="button" id="redo" value="redo"/>
    <input type="button" id="clear" value="Clear Canvas"/>   
    

    //script

      var canvas = new fabric.Canvas('c');
        var text = new fabric.Text('Sample', {
       fontFamily: 'Hoefler Text',
        left: 50,
       top: 30,
        //textAlign: 'center',
        fill: 'navy',
    
    });
    canvas.add(text);
    var vall=10;    
    var l=0;
    var flag=0;
    var k=1;
    var yourJSONString = new Array();
    canvas.observe('object:selected', function(e) {
        //yourJSONString = JSON.stringify(canvas);
        if(k!=10)
    {   
    yourJSONString[k] = JSON.stringify(canvas);
    k++;
    }
    j = k;
        var activeObject = canvas.getActiveObject();
        });
    $("#undo").click(function(){
         if(k-1!=0)
         {
         canvas.clear();
         canvas.loadFromJSON(yourJSONString[k-1]);
         k--;
         l++;
         } 
      canvas.renderAll();   
     });
    
    $("#redo").click(function(){
        if(l > 1)
         {  
          canvas.clear();
          canvas.loadFromJSON(yourJSONString[k+1]);
           k++;
           l--;
          canvas.renderAll();   
         }
     });
    
    $("#clear").click(function(){
        canvas.clear();
      });
     $("#addtext").click(function(){
    var text = new fabric.Text('Sample', {
       fontFamily: 'Hoefler Text',
        left: 100,
        top: 100,
        //textAlign: 'center',
        fill: 'navy',
    
    });
    canvas.add(text);
    }); 
    
    0 讨论(0)
  • 2020-12-04 14:12

    You can use "object:added" and/or "object:removed" for that — fabricjs.com/events

    You can follow this post: Do we have canvas Modified Event in Fabric.js?

    0 讨论(0)
  • 2020-12-04 14:17

    My use case was drawing simple shapes akin to blueprints, so I didn't have to worry about the overhead of saving the whole canvas state. If you are in the same situation, this is very easy to accomplish. This code assumes you have a 'wrapper' div around the canvas, and that you want the undo/redo functionality bound to the standard windows keystrokes of 'CTRL+Z' and 'CTRL+Y'.

    The purpose of the 'pause_saving' variable was to account for the fact that when a canvas is re-rendered it seemingly created each object one by one all over again, and we don't want to catch these events, as they aren't REALLY new events.

    //variables for undo/redo
    let pause_saving = false;
    let undo_stack = []
    let redo_stack = []
    
    canvas.on('object:added', function(event){
        if (!pause_saving) {
            undo_stack.push(JSON.stringify(canvas));
            redo_stack = [];
            console.log('Object added, state saved', undo_stack);
        }
    
    });
    canvas.on('object:modified', function(event){
        if (!pause_saving) {
            undo_stack.push(JSON.stringify(canvas));
            redo_stack = [];
            console.log('Object modified, state saved', undo_stack);
        }
    });
    canvas.on('object:removed', function(event){
        if (!pause_saving) {
            undo_stack.push(JSON.stringify(canvas));
            redo_stack = [];
            console.log('Object removed, state saved', undo_stack);
        }
    });
    
    //Listen for undo/redo 
    wrapper.addEventListener('keydown', function(event){
        //Undo - CTRL+Z
        if (event.ctrlKey && event.keyCode == 90) {
            pause_saving=true;
            redo_stack.push(undo_stack.pop());
            let previous_state = undo_stack[undo_stack.length-1];
            if (previous_state == null) {
                previous_state = '{}';
            }
            canvas.loadFromJSON(previous_state,function(){
                canvas.renderAll();
            })
            pause_saving=false;
        }
        //Redo - CTRL+Y
        else if (event.ctrlKey && event.keyCode == 89) {
            pause_saving=true;
            state = redo_stack.pop();
            if (state != null) {
                undo_stack.push(state);
                canvas.loadFromJSON(state,function(){
                    canvas.renderAll();
                })
                pause_saving=false;
            }
        }
    });
    
    0 讨论(0)
提交回复
热议问题