在Fabric.js中分层画布对象

26

有没有一种通过官方API在Fabric.js画布上分层对象的方法?目前我发现唯一的方法是手动迭代canvas._objects并重新排序,以便按特定顺序进行绘制。是否有更好的方法来做到这一点,而不会(可能)破坏对象?

4个回答

56

[编辑] 我已经更正了以下信息(我的错,我最初想到的是KineticJs api)。

FabricJS有这些API方法可以改变对象的z-index:

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();
     },

谢谢!这个帮我省了很多麻烦。 - Zwade
11
您可以使用canvas.getObjects().indexOf(some_object)获取z-index。有四个命令可用于更改层叠顺序:some_object.sendBackwards()、some_object.sendToBack()、some_object.bringForward()和some_object.bringToFront()。 - markE
啊,天啊,当然了……如果它是一条蛇,它早就咬我了……谢谢。 - dsdsdsdsd
@markE 如何使用这些方法更改 z-ndex 位置???? = canvas.getObjects().indexOf(Obj])+1; - anam
2
@simmisimmi。您可以使用这些画布方法来影响对象相对于其他对象的z-index:bringToFront(object)、bringFoward(object)、sendToBack(object)和sendBackwards(object)。sendBackwards和bringForward都接受第二个对象,您可以将其与之索引相关联。 - markE
显示剩余2条评论

8

步骤1:您可以使用preserveObjectStacking: true

步骤2:然后使用sendtoback、sendtofront等fabricjs选项,如下所示

在此处回答


4

这是我的做法。我为每个织物对象添加了一个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();
}

3
如果您想为所有对象设置特定顺序,而不是将一个对象向前/向后移动,那么迭代调用 bring/send to front/back 会很慢。 您可以借鉴 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)

如果您希望将较小的对象置于前面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接