我在Canvas HTML5中的设计器绘图工具中遇到了一个特定问题。 我正在开发一个动作历史系统(Undo& Redo)。 我正在this question上的 projeqht 的答案上构建我的系统,并序列化历史数组中的图层。核心,解决方案的想法是有效的,但我有一个奇怪的问题。当我点击撤消时,它会创建新图层,但旧图层不会消失。我将附上我的源代码,我也会附上截图,以便您可以看到发生了什么:
源码:
var history = Array(null);
var historyStep = 0;
var arrayNonRemovable = Array('moveLayer','scaleFromOuterNode','scaleFromInnerNode','rotateFromOuterSign','rotateFromInnerSign');
function removeLayerByUndoRedo(l) { 如果(l) { l.destroy(); l.draw(); stage.draw(); } }
function makeHistory(layer,before,after,operation) { historyStep ++; if(historyStep
函数undoHistory() { if(historyStep> 0) { version = history [historyStep]; layer = version.layer; var beforeState = history [historyStep] .before;
removeLayerByUndoRedo(layer);
var layer = Kinetic.Node.create(beforeState, 'container');
stage.add(layer);
stage.draw();
historyStep--;
}
}
Array.prototype.contains = function(obj){ return this.indexOf(obj)> -1; };
截图: 步骤1.创建对象,其中包含更多具有形状的组(线条,矩形,SVG绘图) 步骤2,3,4,5:将物体移动到不同的位置(左上角,左下角,右下角和右上角): 步骤6:第一次按Undo(删除旧图层并从历史记录中重新创建): 第7步:第二次按“撤消”(从历史记录创建新图层,但不删除旧图层) 步骤8,9:再按Undo 2次(与步骤7中相同:创建新图层但保留旧图层):
我做错了吗?我认为它必须是对新图层的引用,如步骤6中删除的图层引用是原始图层,在以下步骤中这些是新图层,因此引用应该是新图层?
答案 0 :(得分:1)
将图层序列化为JSON后,必须执行
yourLayer.destroy()
您的代码似乎这样做,所以我需要更多代码才能找到问题所在。
长期可能性:
我看到您的undoHistory引用了全局layer
,并且还创建了本地layer
。尝试重构你的代码,以确保你没有混合不同的“层”:
function undoHistory(){
if (historyStep>0){
var version = history[historyStep];
var beforeState = history[historyStep].before;
var layer1 = version.layer;
removeLayerByUndoRedo(layer1);
var layer2 = Kinetic.Node.create(beforeState, 'container');
stage.add(layer2);
stage.draw();
historyStep--;
}
}
您不需要在l.destroy()之后执行l.draw()或stage.draw(),因为无论如何都要销毁图层,并且在图层被销毁时自动更新舞台。
以下是layer.destroy的一个工作示例,它可能会有所帮助,直到您可以发布更多代码:
答案 1 :(得分:0)
以下是问讯的内容: 我将图层引用存储在历史数组中。因此,当我创建一个对象时,图层引用存储在历史记录[1]中。我把它移动到3次,我将在历史中为所有步骤提供相同的参考。当我按下撤销时,我正在销毁从存储的引用中调用它的层,我创建了一个新的引用是一个新的引用。在历史中我仍然有旧的引用,它指向NULL。这是问题所在。
我已经修复了它破坏了通过名字调用它的旧图层。 (仅当您为图层指定唯一名称时才有效):stage.find('.'+layer.getName())[0].destroy()