gco*_*gco 15 javascript arrays fabricjs
我正在尝试为我的Fabric.js画布添加撤消/重做功能.我的想法是有一个计数器来计算画布修改(现在它计算对象的添加).我有一个状态数组,它将整个画布作为JSON推送到我的数组.
然后我只想回忆起各州
canvas.loadFromJSON(state[state.length - 1 + ctr],
Run Code Online (Sandbox Code Playgroud)
当用户点击undo时,ctr将减1并将状态加载到数组之外; 当用户点击重做时,ctr将增加1并将状态加载到数组之外.
当我用简单的数字体验这一点时,一切正常.使用真正的面料帆布,我遇到了一些麻烦 - >它不起作用.我认为这取决于我的事件处理程序
canvas.on({
'object:added': countmods
});
Run Code Online (Sandbox Code Playgroud)
jsfiddle在这里:
这里是工作数字唯一的例子(结果见控制台):jsFiddle
gco*_*gco 20
我自己回答了这个问题.
见jsfiddle:
我做了什么:
if (savehistory === true) {
myjson = JSON.stringify(canvas);
state.push(myjson);
} // this will save the history of all modifications into the state array, if enabled
if (mods < state.length) {
canvas.clear().renderAll();
canvas.loadFromJSON(state[state.length - 1 - mods - 1]);
canvas.renderAll();
mods += 1;
} // this will execute the undo and increase a modifications variable so we know where we are currently. Vice versa works the redo function.
Run Code Online (Sandbox Code Playgroud)
仍然需要改进来处理图纸和物体.但这应该很简单.
您可以使用类似diff-patch或 的东西tracking object version。首先,您监听所有对象更改:object:created, object:modified....,通过将 canvas.toObject() 保存在变量中来保存画布的第一个快照;下一次,运行diffpatcher .diff(snapshot,canvas.toObject()),并只保存补丁。要撤消,您可以使用 diffpatcher.reverse 这些补丁。要重做,只需使用函数 diffpatcher.patch。通过这种方式,您可以节省内存,但会增加 CPU 使用率。
使用fabricjs,您可以使用 Object#saveState() 并处理 object: added 以将原始状态保存到数组(用于撤消任务),监听 object:modified、object:removing(用于重做任务)。这种方式更轻量级,也很容易实现。更多最好通过使用循环队列来限制您的历史长度。