Cloning objects in the Canvas using FabricJS

Mandev
3 min readDec 2, 2022

--

When we say that something has been cloned, it means that it has been duplicated or copied. The clone() method allows us to clone any instance. It’s first argument is a callback function while the second argument is the optional properties Array.

 instanceThatWeWantToClone.clone( callback: function, propertiesToInclude: Array)

Using the clone() method

In my previous article, I used the below image as the thumbnail. I used the Text object in order to add the emoji (😩) but I only created one Text object! I know what you’re thinking and Yup, you got that right. I cloned the Text object in order to save myself some time and code.

(_Link to my previous Article Ahem_)

But it’s not just about saving time and code. Cloning objects can really come in handy whenever we want to add a copy-paste feature or duplicate objects so that they can be customized in different ways!

Let us see how we can clone an object in the canvas by using FabricJS.

  1. The first step is to create your favorite object. My favorite object doesn’t exist so I’m simply creating a circle and a Text object cause why not?
  2. We are using the clone() method to clone the circle and text instances
  3. You can see that inside the clone() method, lies an arrow function which takes one parameter called obj.
     var canvas = new fabric.Canvas("canvas", {
backgroundColor: "black",
isDrawingMode: false,
});

// Circle object
var circle = new fabric.Circle({
radius: 50,
fill: "#00bfff",
top: 60,
left: 70,
});

// cloning the circle object
circle.clone((obj) => {
obj.set("top", 55);
obj.set("left", 95);
obj.set("fill", "#ff69b4");
canvas.add(obj);
});

// Text object
var tt = new fabric.Text("🎅", {
fontSize: 83,
left: 80,
top: 180,
});

// cloning the text object
tt.clone((obj) => {
obj.set("scaleX", 0.5);
obj.set("scaleY", 0.5);
obj.set("left", 185);
canvas.add(obj);
});

// Adding them to the canvas
canvas.add(circle, tt);

You can simply paste the above code inside the <script> tag if you don’t want to go through the trouble of typing this. The output should look like this:

Read: Creating canvas using FabricJS

Cloned objects

Implementing the copy-paste feature using FabricJS

The code is pretty self explanatory and I have added comments explaining each line. But remember, to create two buttons and pass the cpFunc() and pasteFunc() functions to the onclick event attribute. Also, if you are wondering, I used this website for styling the buttons and it got the job done really really fast.

Methods used in the example below:

  • getActiveObject() — returns the current active object
  • discardActiveObject() — discards the current active object
  • set() — setter used for setting the properties
  • forEachObject() — Executes a function for each and every object in that group
  • setCoords() — Sets the corner controls based on the current position coordinates, angle, width, height, left and top.
     var canvas = new fabric.Canvas("canvas", {
backgroundColor: "black",
isDrawingMode: false,
});

// Initiating Copy function
function cpFunc() {
canvas.getActiveObject().clone(function (Obj) {
copyToClipboard = Obj;
});
}

// Initiating Paste function
function pasteFunc() {
copyToClipboard.clone(function (clonedObj) {
canvas.discardActiveObject();

// Setting additional properties for the cloned object
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true,
});

// If the object is actively selected only then, add it to the canvas
if (clonedObj.type === "activeSelection") {
clonedObj.canvas = canvas;
clonedObj.forEachObject(function (obj) {
canvas.add(obj);
});

// Setting the corner controls of the cloned object
clonedObj.setCoords();
} else {
canvas.add(clonedObj);
}

copyToClipboard.top += 10;
copyToClipboard.left += 10;

// The cloned object will be the new active object
canvas.setActiveObject(clonedObj);

// Appends a renderAll request
canvas.requestRenderAll();
});
}

// Circle object
var circle = new fabric.Circle({
radius: 50,
fill: "#ed2939",
top: 60,
left: 70,
stroke: "white",
strokeWidth: 3,
});

// Text object
var tt = new fabric.Text("🎅", {
fontSize: 83,
left: 80,
top: 180,
});

// Adding them to the canvas
canvas.add(circle, tt);
Implementing Copy-paste using FabricJS

--

--