Introduction to this article
Like + Follow + Collection = Learned
What do you consider when you copy an element of fabric
? Deep copy the currently selected object and then add it to the canvas?
In fact, fabric.js
provides a cloning method. There is also this demo in the case of fabric.js
official website: Fabric.js demos · Copy and Paste.
This time I will talk about this demo.
Implementation Ideas
Before we get started, let’s clarify our thoughts.
- To copy elements, you must first have elements, so we create some elements on the page (seems like nonsense).
- Before copying, there must be a target to be copied. We can use the
canvas.getActiveObject()
method to get the currently selected element. - When copying, you can use the
clone()
method to clone the currently selected element object. - When pasting, use the
canvas.add()
method to add the cloned element to the canvas.
Of course, there are many small points that need to be paid attention to in actual development, such as how to copy and paste when selecting a group? How to copy and paste when selecting a bunch of elements?
These issues will be discussed later. Let’s first learn how to copy an element.
Hands-on coding
Once you understand the previous ideas, you can start!
Copy a single element
<div> <button οnclick="copy()">Copy</button> <button οnclick="paste()">Paste</button> </div> <canvas id="c" width="500" height="400" style="border: 1px solid #ccc;"></canvas> <script src="//i2.wp.com/unpkg.com/[email protected]/dist/fabric.min.js"></script> <script> const canvas = new fabric.Canvas('c') let rect = new fabric.Rect({ left: 100, top: 50, fill: '#D81B60', width: 100, height: 100, strokeWidth: 2, stroke: '#880E4F', rx: 10, ry: 10, angle: 45 }) canvas.add(rect) // Clone object let _clipboard = null // copy function copy() { //The target element to be copied let target = canvas.getActiveObject() //Clone only when there is a selected element if (target) { target.clone(function(cloned) { _clipboard = cloned // Assign the cloned element to _clipboard }) } } // Paste function paste() { // If the cloned object does not exist, terminate the paste execution. if (!_clipboard) return //Perform the paste operation, clone the cloned object again, and then add it to the canvas. _clipboard.clone(function(clonedObj) { // appropriate displacement clonedObj.set({ left: clonedObj.left + 10, top: clonedObj.top + 10, evented: true, // When set to "false", the object cannot be the target of an event. All events are propagated through it. }) canvas.add(clonedObj) //Add the cloned element to the canvas // Modify the position of the cloned object so that it is easier to observe when pasting multiple times _clipboard.top + = 10 _clipboard.left + = 10 //Modify the currently selected item to the element newly cloned to the canvas canvas.setActiveObject(clonedObj) // Refresh the canvas canvas.requestRenderAll() }) } </script>
First create 2 buttons and 1 canvas in the page, and create an element in the canvas.
In the JS
section, you need to create a variable to save the cloned object. This variable is called _clipboard
.
When performing a copy operation, it is necessary to determine whether the element object is currently selected.
When performing a paste operation, it is necessary to determine whether the element object is currently cloned.
Copy Group
In fact, copying a group is the same as copying a single element. It is also necessary to obtain the currently selected object. The group can be regarded as an element object.
The code is the same as above, just change the single element into a group. I quote the demo from the official website of fabric.js
//Omit some code let circle1 = new fabric.Circle({ radius: 65, fill: '#039BE5', left: 0 }) let circle2 = new fabric.Circle({ radius: 65, fill: '#4FC3F7', left: 110, Opacity: 0.7 }) let group = new fabric.Group([circle1, circle2, ], { left: 40, top: 250 }) canvas.add(group)
Just add the previous copy and paste code.
Copy selected elements
The operation of copying box-selected elements will be relatively complicated, but it is only a matter of time.
Because more than one element is selected, all elements need to be traversed when pasting, using the forEachObject
method provided by fabric.js
.
//Omit some code // Paste function paste() { // If the cloned object does not exist, terminate the paste execution. if (!_clipboard) return _clipboard.clone(function(clonedObj) { // appropriate displacement clonedObj.set({ left: clonedObj.left + 10, top: clonedObj.top + 10, evented: true }) // Traverse and paste all selected elements clonedObj.canvas = canvas clonedObj.forEachObject(function(obj) { canvas.add(obj) }) clonedObj.setCoords() // appropriate displacement _clipboard.top + = 10 _clipboard.left + = 10 // Select all newly pasted elements canvas.setActiveObject(clonedObj) }) }
The last thing that needs to be done is to be compatible with the selection of a single element or the selection of multiple elements.
After obtaining the currently selected object, there is a type
attribute. When multiple elements are selected, the value of type
will become activeSelection
, and we will You can use this to determine whether a single element is currently selected or multiple elements are selected.
//Omit some code // Paste function paste() { // If the cloned object does not exist, terminate the paste execution. if (!_clipboard) return _clipboard.clone(function(clonedObj) { // appropriate displacement clonedObj.set({ left: clonedObj.left + 10, top: clonedObj.top + 10, evented: true }) if (clonedObj.type === 'activeSelection') { // Multiple elements are selected // Traverse and paste all selected elements clonedObj.canvas = canvas clonedObj.forEachObject(function(obj) { canvas.add(obj) }) clonedObj.setCoords() } else { // Select an element canvas.add(clonedObj) _clipboard.top + = 10 _clipboard.left + = 10 } // appropriate displacement _clipboard.top + = 10 _clipboard.left + = 10 // Select all newly pasted elements canvas.setActiveObject(clonedObj) // Refresh the canvas canvas.requestRenderAll() }) }
In addition to the above mouse operations, we can also achieve the above effect by monitoring the keyboard’s ctrl + c
and ctrl + v
(mac monitoring command).
Leave this part of the work to the workers, I’ll leave first.
Code Warehouse
The complete code for this article can be obtained through the link below.
? Copy and paste elements
Recommended Reading
“Fabric.js from entry to _ _ _ _ _ _”
“Fabric.js dragging vertices to modify polygon shapes”
“Fabric.js explains the official demo: Stickman”
《Fabric.js Custom Control》
《What should I do if the Fabric.js style is not updated? 》
《Fabric.js Pattern Brush (Brush)》
Like + Follow + Collection = Learned Code Warehouse