替换 FabricJS 中的对象?
Replace an object in FabricJS?
为了实现 undo/redo 功能,我构建了一个数组“history
”,其中填充了基于 canvas.on()
事件的最新更改。
console.log转储:
History:
(3) […]
0: Object { target: {…} } //first object added
1: Object { e: mouseup, target: {…}, transform: {…}, … } //first object modified
2: Object { target: {…} } //another object added
length: 3
要返回更改堆栈,我想使用 history[step].target
,其中包含现阶段修改的对象 (step
)。
我现在正在寻找一种方法来覆盖 fabric 对象数组中的对象。
函数 canvas.item(0)
给出了当前 canvas 位置 0 处的对象,但是我如何用不同的对象(来自 history[].target
数组)覆盖该对象?
注意:我为 undo/redo 找到的解决方案似乎是基于将整个 canvas 序列化为 JSON 并将其保存到 JSON 的数组中。我不想这样做,因为总是 serialize/unserialize 整个 canvas 和其中的 x 个对象似乎有点简单,只是为了撤消一个小的更改,并且历史记录包含许多关于更改内容的有用信息以及在哪个对象上。
注意 2:当然我可能只 canvas.remove(canvas.item(0))
然后 canvas.add(history[x].target)
,但是不幸的是,当有多个对象时,这会弄乱我的对象堆栈,因为 canvas.item(1)
变成 canvas.item(0)
并且还原的更改现在变为 canvas.item(1)
(或 2、3... 等等,具体取决于 canvas 上的项目数)。然后,当我喜欢根据对象在对象堆栈中的位置显示的对象列表时,它会重新排列并可能使用户感到困惑。
据我所知,无法覆盖对象。
但这可能对您的 Note2 有所帮助:
除了 Gabriele Petriolis 的评论外,您还可以在插入后将对象定位在堆栈中:
Canvas.moveTo()
Canvas.bringToFront()
Canvas.bringForward()
Canvas.sendBackwards()
Canvas.sendToBack()
这是一个简单的例子。
给定 canvas 上的 2 个矩形,一个函数将在这 2 个的中间添加一个,另一个将替换位置 0 的那个。
canvas#insertAt 确实按照@gabriele-petroli
的建议工作
var c = new fabric.Canvas('c');
c.add(new fabric.Rect({ fill: 'blue', width: 100, height: 100 }));
c.add(new fabric.Rect({ fill: 'green', left: 150, width: 100, height: 100 }));
var redRect = new fabric.Rect({ fill: 'red', left: 75, width: 100, height: 100 });
var purpleRect = new fabric.Rect({ fill: 'purple', left: 0,
width: 100, height: 100 });
setTimeout(function() {
c.insertAt(purpleRect, 0, true);
c.insertAt(redRect, 1);
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.5.0/fabric.min.js"></script>
<canvas id="c" width="500" height="500" ></canvas>
为了实现 undo/redo 功能,我构建了一个数组“history
”,其中填充了基于 canvas.on()
事件的最新更改。
console.log转储:
History:
(3) […]
0: Object { target: {…} } //first object added
1: Object { e: mouseup, target: {…}, transform: {…}, … } //first object modified
2: Object { target: {…} } //another object added
length: 3
要返回更改堆栈,我想使用 history[step].target
,其中包含现阶段修改的对象 (step
)。
我现在正在寻找一种方法来覆盖 fabric 对象数组中的对象。
函数 canvas.item(0)
给出了当前 canvas 位置 0 处的对象,但是我如何用不同的对象(来自 history[].target
数组)覆盖该对象?
注意:我为 undo/redo 找到的解决方案似乎是基于将整个 canvas 序列化为 JSON 并将其保存到 JSON 的数组中。我不想这样做,因为总是 serialize/unserialize 整个 canvas 和其中的 x 个对象似乎有点简单,只是为了撤消一个小的更改,并且历史记录包含许多关于更改内容的有用信息以及在哪个对象上。
注意 2:当然我可能只 canvas.remove(canvas.item(0))
然后 canvas.add(history[x].target)
,但是不幸的是,当有多个对象时,这会弄乱我的对象堆栈,因为 canvas.item(1)
变成 canvas.item(0)
并且还原的更改现在变为 canvas.item(1)
(或 2、3... 等等,具体取决于 canvas 上的项目数)。然后,当我喜欢根据对象在对象堆栈中的位置显示的对象列表时,它会重新排列并可能使用户感到困惑。
据我所知,无法覆盖对象。
但这可能对您的 Note2 有所帮助:
除了 Gabriele Petriolis 的评论外,您还可以在插入后将对象定位在堆栈中:
Canvas.moveTo()
Canvas.bringToFront()
Canvas.bringForward()
Canvas.sendBackwards()
Canvas.sendToBack()
这是一个简单的例子。
给定 canvas 上的 2 个矩形,一个函数将在这 2 个的中间添加一个,另一个将替换位置 0 的那个。
canvas#insertAt 确实按照@gabriele-petroli
的建议工作var c = new fabric.Canvas('c');
c.add(new fabric.Rect({ fill: 'blue', width: 100, height: 100 }));
c.add(new fabric.Rect({ fill: 'green', left: 150, width: 100, height: 100 }));
var redRect = new fabric.Rect({ fill: 'red', left: 75, width: 100, height: 100 });
var purpleRect = new fabric.Rect({ fill: 'purple', left: 0,
width: 100, height: 100 });
setTimeout(function() {
c.insertAt(purpleRect, 0, true);
c.insertAt(redRect, 1);
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.5.0/fabric.min.js"></script>
<canvas id="c" width="500" height="500" ></canvas>