web-dev-qa-db-ja.com

Fabric.jsでオブジェクトを複製する

単純な関数を使用して、Fabric.jsのキャンバスに選択したオブジェクトのクローンを作成しています。

function duplicateObj() {
  var obj = canvas.getActiveObject();
  var clone = fabric.util.object.clone(obj);
  clone.set({left: 100,top: 100});
  canvas.add(clone); 
}

それは絶対にうまくいきます。オブジェクトを操作し、クローンが不要になり、それを選択して削除すると、オブジェクト、クローン、および元のオブジェクトの両方が削除されます。削除機能は次のとおりです。

function deleteObj() {
  var obj = canvas.getActiveObject();
  canvas.fxRemove(obj);
}

オブジェクトは同じです。オブジェクトのクローンを作成し、元のクローンから独立させる方法はありますか?私はこれを試しました:

function duplicateObj() {
  var obj = canvas.getActiveObject();
  var clone = fabric.util.object.clone(obj);
  clone.initialize();
  $.extend(clone, obj);
  fabric.util.object.extend(clone, obj);
  clone.set({left: 100,top: 100});
  canvas.add(clone); 
}

それは機能しますが、オブジェクトは再び同じであり、初期化のみを使用すると、プロパティが設定されたオブジェクトになります。

11
Benick

これが解決策です

 var object = fabric.util.object.clone(canvas.getActiveObject());
    object.set("top", object.top+5);
    object.set("left", object.left+5);
     canvas.add(object);
13
swapnil gandhi

クローンに対するアクションが元のオブジェクトに影響を与えるという同様の問題がありました。オブジェクトをシリアル化し、新しいオブジェクトに逆シリアル化することを選択しました。

var copyData = canvas.getActiveObject().toObject();
fabric.util.enlivenObjects([copyData], function(objects) {
  objects.forEach(function(o) {
    o.set('top', o.top + 15);
    o.set('left', o.left + 15);
    canvas.add(o);
  });
  canvas.renderAll();
});
3
Brandon Joyce

fabricjs2.0の場合

    $(".copy").on("click", function () {
                    var activeObject = canvas.getActiveObject();
                    activeObject.clone(function (cloned) {
                        canvas.discardActiveObject();
                        cloned.set({
                            top: cloned.top + 20,
                            evented: true
                        });
                        if (cloned.type === 'activeSelection') {
                            // active selection needs a reference to the canvas.
                            cloned.canvas = canvas;
                            cloned.forEachObject(function (obj) {
                                canvas.add(obj);
                            });
                            cloned.setCoords();
                        } else {
                            canvas.add(cloned);
                        }
                        canvas.setActiveObject(cloned);
                        canvas.requestRenderAll();
                    });
    });
3
AZinkey

これは私にとって非常にうまく機能し、複製されたオブジェクトは元のオブジェクトから完全にリンクされていません。

var object = canvas.getActiveObject();

object.clone(function(clone) {
    canvas.add(clone.set({
        left: object.left + 10, 
        top: object.top + 10
    }));
});

そして、選択したすべてのオブジェクトのクローンを作成することができます。

var activeObjects = canvas.getActiveObjects();

if (activeObjects) {
    activeObjects.forEach(function(object) {

        object.clone(function(clone) {
            canvas.add(clone.set({
                left: object.left + 10, 
                top: object.top + 10
            }));
        })

    });
}

お役に立てば幸いです。

1

あなたが使用することができます

var obj = canvas.getActiveObject();
obj.clone(function(c) {
   canvas.add(c.set({ left: 100, top: 100, angle: -15 }));
});

ここでそれが機能しているのを見ることができます: http://fabricjs.com/opacity_mouse_move/

0
Diogo Garcia

これが、選択したオブジェクトまたはグループのクローン作成の実装です。

https://jsfiddle.net/milanhlinak/rxtjm7w0/1/

<!DOCTYPE html>
<html>

<head>
    <script type="text/javascript" src="lib/jquery-3.1.1.min.js"></script>
    <script type="text/javascript" src="lib/fabric.min.js"></script>
</head>

<body>

    <button onclick="cloneSelected()">Clone selected</button>
    <canvas id="canvas" style="border: 1px solid #cccccc"></canvas>

    <script>
        var canvas = new fabric.Canvas('canvas', {
            width: 500,
            height: 500,
        });

        canvas.add(new fabric.Rect({
            left: 100,
            top: 100,
            width: 50,
            height: 50,
            fill: '#faa'

        }));
        canvas.add(new fabric.Circle({
            left: 300,
            top: 300,
            radius: 25,
            fill: '#afa'
        }));


        function cloneSelected() {
            console.log('cloneSelected');

            var activeObject = canvas.getActiveObject();
            var activeGroup = canvas.getActiveGroup();

            if (activeObject) {
                console.log('object selected');

                var clonedObject = null;
                var json = activeObject.toJSON();
                if (json.type == 'rect') {
                    clonedObject = new fabric.Rect(json);
                } else if (json.type == 'circle') {
                    clonedObject = new fabric.Circle(json);
                } else {
                    console.log('unknown object type: ' + json.type);
                    return;
                }

                var oldLeft = clonedObject.getLeft();
                var oldTop = clonedObject.getTop();

                clonedObject.setLeft(oldLeft + 10);
                clonedObject.setTop(oldTop + 10);

                var boundingRect = clonedObject.getBoundingRect(true);
                if (boundingRect.left + boundingRect.width > canvas.getWidth()) {
                    clonedObject.setLeft(oldLeft);
                }
                if (boundingRect.top + boundingRect.height > canvas.getHeight()) {
                    clonedObject.setTop(oldTop);
                }

                canvas.add(clonedObject);
                canvas.setActiveObject(clonedObject);
                canvas.renderAll();
                console.log('selected object cloned');

            } else if (activeGroup) {
                console.log('group selected');

                canvas.discardActiveGroup();

                var clonedObjects = [];

                activeGroup.getObjects().forEach(function (object) {

                    var clonedObject = null;

                    var json = object.toJSON();
                    if (json.type == 'rect') {
                        clonedObject = new fabric.Rect(json);
                    } else if (json.type === 'circle') {
                        clonedObject = new fabric.Circle(json);
                    } else {
                        console.log('unknown object type: ' + json.type);
                        return;
                    }

                    clonedObject.setCoords();
                    canvas.add(clonedObject);
                    clonedObject.set('active', true);
                    clonedObjects.Push(clonedObject);
                });

                var group = new fabric.Group(clonedObjects.reverse(), {
                    canvas: canvas
                });

                group.addWithUpdate(null);

                var oldLeft = group.getLeft();
                var oldTop = group.getTop();

                group.setLeft(oldLeft + 10);
                group.setTop(oldTop + 10);

                var boundingRect = group.getBoundingRect(true);
                if (boundingRect.left + boundingRect.width > canvas.getWidth()) {
                    group.setLeft(oldLeft);
                }
                if (boundingRect.top + boundingRect.height > canvas.getHeight()) {
                    group.setTop(oldTop);
                }

                group.setCoords();
                canvas.setActiveGroup(group);
                group.saveCoords();
                canvas.renderAll();
                console.log('selected objects cloned');
            } else {
                console.log('no object selected');
            }

        }
    </script>

</body>

</html>
0
Milan Hlinák