Layering canvas objects in Fabric.js

前端 未结 3 1757
再見小時候
再見小時候 2021-01-30 14:25

Is there a way to layer objects on a Fabric.js canvas via the official API? Right now the only way I have found to do it is to manually iterate through the canvas._objects and r

相关标签:
3条回答
  • step 1 : You can Use preserveObjectStacking: true

    step 2 : then use sendtoback,sendtofront....fabricjs options like below

    Answered over here

    0 讨论(0)
  • 2021-01-30 15:14

    [Edit] I've corrected my info below (my bad, I was originally thinking of the KineticJs api).

    FabricJS has these API methods that change the z-index of objects:

    canvas.sendBackwards(myObject)
    canvas.sendToBack(myObject)
    canvas.bringForward(myObject)
    canvas.bringToFront(myObject)
    

    Under the covers, FabricJs changes the z-index by removing the object from the getObjects() array and splicing it back in the desired position. It has a nice optimization that checks for intersecting objects.

    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();
         },
    
    0 讨论(0)
  • 2021-01-30 15:15

    If you want to set a specific ordering for all objects, instead of moving one object forward/backward, iterative calls to bring/send to front/back are slow.

    You can use the code of bringToFront as inspiration to speed this use case up: https://github.com/kangax/fabric.js/blob/586e61dd282b22c1d50e15c0361875707e526fd8/src/static_canvas.class.js#L1468

    And do this:

    fabric.Canvas.prototype.orderObjects = function(compare) {
        this._objects.sort(compare);
        this.renderAll();
    }
    

    Where compare defines the sorting, like:

    function compare(x,y) {
        return x.getWidth() * x.getHeight() < y.getWidth() * y.getHeight();
    }
    
    some_canvas.orderObjects(compare)
    

    If you wish to bring smaller objects to the front.

    0 讨论(0)
提交回复
热议问题