有没有办法通过官方 API 在 Fabric.js 画布上分层对象?现在我发现这样做的唯一方法是手动遍历 canvas._objects 并重新排序它们,以便它们以特定顺序绘制。有没有更好的方法来做到这一点,它不会(可能)破坏对象?
问问题
42236 次
4 回答
54
[编辑] 我在下面更正了我的信息(我的错,我最初考虑的是 KineticJs api)。
FabricJS 有这些改变对象 z-index 的 API 方法:
canvas.sendBackwards(myObject)
canvas.sendToBack(myObject)
canvas.bringForward(myObject)
canvas.bringToFront(myObject)
在幕后,FabricJs 通过从 getObjects() 数组中删除对象并将其拼接回所需位置来更改 z-index。它有一个很好的优化,可以检查相交的对象。
bringForward: function (object) {
var objects = this.getObjects(),
idx = objects.indexOf(object),
nextIntersectingIdx = idx;
// if object is not on top of stack (last item in an array)
if (idx !== objects.length-1) {
// traverse up the stack looking for the nearest intersecting object
for (var i = idx + 1, l = this._objects.length; i < l; ++i) {
var isIntersecting = object.intersectsWithObject(objects[i]) ||
object.isContainedWithinObject(this._objects[i]) ||
this._objects[i].isContainedWithinObject(object);
if (isIntersecting) {
nextIntersectingIdx = i;
break;
}
}
removeFromArray(objects, object);
objects.splice(nextIntersectingIdx, 0, object);
}
this.renderAll();
},
于 2013-02-23T05:05:27.887 回答
9
于 2017-01-26T18:01:12.190 回答
3
如果您想为所有对象设置特定的顺序,而不是向前/向后移动一个对象,迭代调用将/发送到前/后是很慢的。
您可以使用以下代码bringToFront
作为灵感来加速此用例:https ://github.com/kangax/fabric.js/blob/586e61dd282b22c1d50e15c0361875707e526fd8/src/static_canvas.class.js#L1468
并这样做:
fabric.Canvas.prototype.orderObjects = function(compare) {
this._objects.sort(compare);
this.renderAll();
}
其中 compare 定义了排序,例如:
function compare(x,y) {
return x.getWidth() * x.getHeight() < y.getWidth() * y.getHeight();
}
some_canvas.orderObjects(compare)
如果您想将较小的物体放在前面。
于 2017-07-06T07:43:57.727 回答
1
我就是这样做的。我为每个织物对象添加了一个 zIndex 属性,然后在将它们添加到画布后调用了一个排序函数:
const CIRCLE_INDEX = 1
let object = new fabric.Circle({
left: 10,
top: 10,
radius: 5
...other properties
zIndex: CIRCLE_INDEX
});
然后在添加对象后调用这样的函数
const sortObjects = () => {
canvas._objects.sort((a, b) => (a.zIndex > b.zIndex) ? 1 : -1);
canvas.renderAll();
}
于 2021-04-23T13:07:15.923 回答