Cloning objects in Fabric.js

I clone the selected object on the canvas in Fabric.js using a simple function.

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

It works absolutely fine. Now, if I work with an object and the clone is no longer required, and I select and delete it, both objects, the clone and the original object are deleted. Delete function:

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

The objects are the same. Is there a way to clone objects and make the clone independent of the original? I tried this:

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

It works, however the objects are repeated again, and if I use only initialization, I end the object that now has properties.

+8
html5-canvas fabricjs
source share
6 answers

here is the solution

  var object = fabric.util.object.clone(canvas.getActiveObject()); object.set("top", object.top+5); object.set("left", object.left+5); canvas.add(object); 
+11
source share

I had a similar problem when actions on a clone affected the original object. I decided to just serialize the object and deserialize it into a new object:

 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
source share

you can use

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

Here you can see how it works: http://fabricjs.com/opacity_mouse_move/

0
source share

Here is my implementation of cloning a selected object or group.

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
source share

for fabricjs 2.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(); }); }); 
0
source share

Check out the demo for copy and paste here: http://fabricjs.com/copypaste

Here is the code to copy / paste or clone the selected object.

 function Clone() { Copy(); Paste() } function Copy() { // clone what are you copying since you // may want copy and paste on different moment. // and you do not want the changes happened // later to reflect on the copy. canvas.getActiveObject().clone(function(cloned) { _clipboard = cloned; }); } function Paste() { // clone again, so you can do multiple copies. _clipboard.clone(function(clonedObj) { canvas.discardActiveObject(); clonedObj.set({ left: clonedObj.left + 10, top: clonedObj.top + 10, evented: true, }); if (clonedObj.type === 'activeSelection') { // active selection needs a reference to the canvas. clonedObj.canvas = canvas; clonedObj.forEachObject(function(obj) { canvas.add(obj); }); // this should solve the unselectability clonedObj.setCoords(); } else { canvas.add(clonedObj); } _clipboard.top += 10; _clipboard.left += 10; canvas.setActiveObject(clonedObj); canvas.requestRenderAll(); }); } 
-one
source share

All Articles