web-dev-qa-db-fra.com

Superposition d'objets de canevas dans Fabric.js

Existe-t-il un moyen de superposer des objets sur un canevas Fabric.js via l'API officielle? À l'heure actuelle, la seule façon de le faire est de parcourir manuellement les objets canvas._objects et de les réorganiser afin qu'ils soient dessinés dans un ordre spécifique. Y a-t-il une meilleure façon de faire cela qui ne brise pas (potentiellement) l'objet?

23
Zwade

[Modifier] J'ai corrigé mes informations ci-dessous (ma mauvaise, je pensais à l'origine à l'api KineticJs).

FabricJS a ces méthodes API qui modifient le z-index des objets:

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

Sous les couvertures, FabricJs modifie le z-index en supprimant l'objet du tableau getObjects () et en le recollant dans la position souhaitée. Il a une belle optimisation qui vérifie les objets qui se croisent.

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

étape 1: vous pouvez utiliser preserveObjectStacking: true

étape 2: puis utilisez les options sendtoback, sendtofront .... fabricjs comme ci-dessous

Répondu ici

4
vijay

Si vous souhaitez définir un ordre spécifique pour tous les objets, au lieu de déplacer un objet vers l'avant/vers l'arrière, les appels itératifs pour amener/envoyer vers l'avant/l'arrière sont lents.

Vous pouvez utiliser le code de bringToFront comme source d'inspiration pour accélérer ce cas d'utilisation: https://github.com/kangax/fabric.js/blob/586e61dd282b22c1d50e15c0361875707e526fd8/src/static_canvas.class.js # L1468

Et faites ceci:

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

Où compare définit le tri, comme:

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

some_canvas.orderObjects(compare)

Si vous souhaitez amener des objets plus petits à l'avant.

1
Herbert