【问题标题】:Fabric.js Undo Redo Functionality causing 2 steps at a timeFabric.js 撤消重做功能一次导致 2 个步骤
【发布时间】:2023-03-28 08:37:01
【问题描述】:

当我使用多种方式添加对象时,我无法让撤消/重做工作。我的编辑器有一个添加图像、背景和文本的按钮。

因此,我相信(如果我错了,请纠正我)每次调用添加图像、背景或文本的函数时,以及每次修改画布时,我都需要调用 updateModifications() 函数。我相当确定问题是 updateModifications 在整个文档中被调用了太多次。

function remove(){
  console.log(canvas.getActiveObject());
  var activeObjects = canvas.getActiveObjects();
      canvas.discardActiveObject()
      if (activeObjects.length) {
        canvas.remove.apply(canvas, activeObjects);
      }
      updateModifications(true);
}
canvas.on({
  'object:modified': function () {
    updateModifications(true);
  },
  'object:added': function() {
    updateModifications(true);
  }

});
function addText() {
  prodName = localStorage.getItem('storedName');
  var textObj = new fabric.IText(prodName, {
    fontSize: 22,
    top: 362.5,
    left: 262.5,
    hasControls: true,
    fontWeight: 'bold',
    fontFamily: '"Montserrat",sans-serif',
    fontStyle: 'normal',
    centeredrotation: true,
    originX: 'center',
    originY: 'center'
  });
  canvas.insertAt(textObj,0).setActiveObject(textObj);
  textToFront();
  canvas.renderAll();
  updateModifications(true);
}

这会在代码based on zaid's SO question 时产生一些问题;

var mods = 0;
var state = [];
function updateModifications(savehistory) {
  if (savehistory === true) {
      myjson = JSON.stringify(canvas);
      state.push(myjson);
  }
}

undo = function undo() {
  if (mods < state.length) {
      canvas.clear().renderAll();
      canvas.loadFromJSON(state[state.length - 1 - mods - 1]);
      canvas.renderAll();
      mods += 1;
  }
}

redo = function redo() {
  if (mods > 0) {
      canvas.clear().renderAll();
      canvas.loadFromJSON(state[state.length - 1 - mods + 1]);
      canvas.renderAll();
      mods -= 1;
  }
}

【问题讨论】:

    标签: fabricjs undo-redo


    【解决方案1】:

    当您调用 addText() 时,您正在调用 updateModifications(),然后有一个事件侦听器“object: added”也调用 updateModifications()。要么删除事件侦听器,要么干脆不要在 addText() 中调用 updateModifications()。

    不确定然后交配,但这在织物 2.5 中对我有用:

    var CanvasState = [];
    var CanvasStateIndex = -1;
    saveCanvas()
    
    function refreshCanvas(){
      canvas.renderAll.bind(canvas);
    }
    
    function saveCanvas(){
      var newState = canvas.toJSON();
      CanvasState.push(newState);
      CanvasStateIndex = CanvasStateIndex +1;
      while (CanvasStateIndex < (CanvasState.length)-1){
        CanvasState.pop();
      }
    }
    
    function undo(){
      if (CanvasStateIndex >= 0){
        CanvasStateIndex = CanvasStateIndex -1;
        var jsonCanvas = CanvasState[CanvasStateIndex];
        canvas.loadFromJSON(jsonCanvas, refreshCanvas, function(o, obj){ 
        })
      } else{
        console.log('undo error CanvasStateIndex = '+CanvasStateIndex)
      }
    }
    
    function redo(){
      if (CanvasStateIndex < CanvasState.length -1){
        CanvasStateIndex = CanvasStateIndex +1;
        var jsonCanvas = CanvasState[CanvasStateIndex];
        canvas.loadFromJSON(jsonCanvas, refreshCanvas, function(o, obj){
        })
      }else{
        console.log('redo error CanvasStateIndex = '+CanvasStateIndex)
      }
    };
    

    【讨论】:

    • 谢谢,除了添加对象和修改对象之外,我尝试将其从任何地方删除,但它似乎仍然奇怪地返回了 2 次。
    • 好的,不知道出了什么问题,但编辑了我的答案以提供适合我的替代方案
    • 感谢更新脚本,撤消当前返回 1 步,重做抛出:重做错误 CanvasStateIndex = 2。我已将 saveCanvas 添加到仅对象:添加和对象:修改
    • 嘿,很抱歉有一个截止日期!如果您尝试重做超出“堆栈”的顶部,您应该只会看到该错误。您是否尝试过删除事件侦听器并手动调用 saveCanvas() (即作为添加/修改事物的函数的一部分)?如果您的函数两次修改一个对象,您将调用 saveCanvas() 两次
    • 这绝对是问题所在。谢谢你的帮助!我必须找出防止它翻倍的最佳方法。
    猜你喜欢
    • 2013-10-03
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多