web-dev-qa-db-ja.com

Fabric.jsでのキャンバスオブジェクトのレイヤー化

公式APIを介してFabric.jsキャンバス上にオブジェクトをレイヤー化する方法はありますか?今私がそれを行うことがわかった唯一の方法は、canvas._objectsを手動で反復し、それらを特定の順序で描画されるように並べ替えることです。オブジェクトを(潜在的に)壊さない、これを行うより良い方法はありますか?

23
Zwade

[編集]以下の情報を修正しました(悪いことに、元々は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();
     },
46
markE

ステップ1:preserveObjectStacking: true

ステップ2:次に、sendtoback、sendtofront .... fabricjsオプションを以下のように使用します

ここで回答

4
vijay

すべてのオブジェクトに特定の順序を設定する場合は、1つのオブジェクトを前後に移動するのではなく、前面/背面に移動/送信するための反復呼び出しが遅くなります。

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)

小さな物を前面に持ってきたい場合。

1
Herbert