我正在尝试为我的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
我有一个带有可添加对象的画布,以及撤消和重做按钮.正如你在我的例子中所看到的,我能够撤消/重做一次,但事情就会破裂; 通过这个我的意思是我可以添加一个对象并删除它,但是如果我移动添加的对象并点击撤消,它应该移动到我以前的位置,但它会从画布中消失.
我正在使用fabric.js 1.7.22.
我的代码:
var canvas = this.__canvas = new fabric.Canvas('canvas', {
backgroundColor: 'grey',
centeredScaling: true
});
canvas.setWidth(400);
canvas.setHeight(600);
canvas. preserveObjectStacking = true;
// Add Text
function Addtext() {
var text = new fabric.IText("Tape and Type...", {
fontSize: 30,
top: 10,
left: 10,
textAlign: "center",
});
canvas.add(text);
canvas.centerObject(text);
canvas.setActiveObject(text);
text.enterEditing();
text.selectAll();
canvas.renderAll();
canvas.isDrawingMode = false;
}
// Undo Redo
canvas.on('object:added',function(){
if(!isRedoing){
h = [];
}
isRedoing = false;
});
var isRedoing = false;
var h = [];
function undo(){ …Run Code Online (Sandbox Code Playgroud)在Fabric.js中,我们有Object修改过的事件,比如object:modified.我们是否有整个画布的类似事件.
实际上我正在尝试实现撤消和重做功能.我将画布保存为JSON,如果发生了某些事情并再次加载它以进行撤消功能.
我们是否在Fabric.js中为此功能提供了更好的解决方案?
编辑:这个问题的范围有所改变.请参阅下面的更新.
我一直在为fabric.js做一些撤销/重做(见小提琴).虽然相当天真,但它大部分都在工作(用于添加/移除/移动或调整单个对象的大小或添加/删除对象组),但不适用于移动或调整对象组.在小提琴中,注意onObjectSelected()函数的控制台输出.
要查看我的意思,请在小提琴画布上绘制一些对象,然后单独移动或调整它们.撤消/重做按预期工作.但是,当选择并移动组时,我看不到如何检索组内对象的更新位置,这意味着撤消/重做无法恢复正确的值.
// onObjectSelected function quoted here to satisfy stackoverflow
// question requirements. See full jsfiddle for context.
for (i in canvas.getObjects()) {
if (canvas.item(i).active === true ) {
console.log(canvas.item(i));
selectedObject.push({
"itemNum" : i,
"svdObject" : fabric.util.object.clone(canvas.item(i))
});
}
}
Run Code Online (Sandbox Code Playgroud)
原因似乎是当作为一组移动或调整大小时,对象位置/比例不会更新.我尝试了各种各样的东西,包括为所有对象运行setCoords(),但这没有帮助.所以如果有人能够发现我做错了什么,或者知道如何解决这个问题,我会很感激.
编辑:为了澄清,这只是一个普通的撤销/重做系统,当用户修改它们时,使用两个数组来存储画布上对象的属性.单击撤消或重做时,属性将应用于画布上的对象.我遇到的问题是,当选择对象组并随后进行修改时,我不知道如何捕获某些属性,例如组中对象的位置,因为组内对象的属性是由于某种原因将对象修改为组时未更新.
更新:我已经了解到,当对象位于用户选择的组中时,对象位置将相对于其所在的组进行记录,而不再是画布,这是有意义的.因此,当处理组中的对象时,将其左/顶部坐标添加到组左/顶部坐标以计算对象相对于画布的坐标.scaleX/Y应乘以group scaleX/Y.
更新:我已经管理过这样做我想要的东西(见新小提琴).我已经了解了fabric的'stateful'标志,stateProperties数组和hasStateChanged方法,这将简化事情.这些文档很少,到目前为止我还没有成功地在这个解决方案中使用它们.使用这些的使用技巧或示例代码将不胜感激.具体来说,我希望能够控制保存哪些属性,因为我不需要保存所有可更改的属性.
onObjectSelected目前看起来像这样:
function onObjectSelected() {
selectedObject = [];
for (i in canvas.getObjects()) {
if (canvas.item(i).active === true) {
// shft-ctrl-j to …Run Code Online (Sandbox Code Playgroud) 以下代码片段在红色方块上方有一个绿色方块
bring forward按钮单击后,bring forward方块的顺序已改变。据我了解,这些项目应该保持相同的顺序,但随着进一步单击按钮,这些项目应该逐渐移动到其他未选定的项目之上。
如果取消选择并重复实验,您将看到它们再次切换。
有任何想法吗?
var canvas = new fabric.Canvas('c',
{
preserveObjectStacking : true
});
var rect = new fabric.Rect({
left: 10, top: 10,
fill: 'red',
width: 100, height: 100,
hasControls: true
});
canvas.add(rect);
var rect2 = new fabric.Rect({
left: 40, top: 40,
fill: 'green',
width: 100, height: 100,
hasControls: true
});
canvas.add(rect2);
$("#bringForward").click(function()
{
var items = canvas.getActiveObject() || canvas.getActiveGroup();
if(items)
items.bringForward();
});Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.6/fabric.min.js"></script>
<button id="bringForward">Bring Forward</button>
<canvas id="c" …Run Code Online (Sandbox Code Playgroud)