In this article
I’ve listed three ways to change an image in fabric.js.
It also includes the operation of changing pictures in the group.
Environment and Version
Chrome version: 96.0.4664.45
Fabric.js version: 4.6.0
I developed in a native environment and also provided a copy of the code developed in the Vue3 environment (link at the end of this article).
hands-on
PNG and bhikkhu.png, which were found on the iconfont website.
If you want to use the image of this case, you can obtain it in the warehouse provided at the end of this article.
Scenario 1: Change the SRC of the image element
If you add an Image object to the Canvas, you can use image.setsrc to set the new Image, and then refresh the Canvas with Canvas.renderall.
<style>
canvas {
border: 1px solid #ccc;
}
</style>
<button onclick="change()">The images</button>
<canvas width="300" height="300" id="canvas"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script>
<script>
// instantiate canvas
canvas = new fabric.Canvas('canvas')
// Create a picture object
fabric.Image.fromURL('.. /.. /images/Agumon.png'.oImg= > {
// Add the image object to the canvas
canvas.add(oImg)
})
// Replace the image event
function change() {
// Get the image object. Because in this case there is only one element in the canvas, the first element of the array retrieved with getObjects() is the image
const img = canvas.getObjects()[0]
// Use the setSrc method to change the image. The second parameter is the callback function. Refresh the canvas in the callback function
img.setSrc('.. /.. /images/Bhikkhu.png'.() = > {
canvas.renderAll()
})
}
</script>
Copy the code
The above scenario is the simplest.
If you have multiple shapes and images on the canvas, you may need to add some custom attributes to the canvas when creating the image.
Use fabric.getobjects ().find() to search.
Find () is the original method of the array.
Scenario 2: Modifying images within the group (no caching)
Create groups are cached by default, and rerendering using canvas.renderall () does not update images if cached.
Therefore, you need to specify Group. ObjectCaching when creating a Group.
<style>
canvas {
border: 1px solid #ccc;
}
</style>
<button onclick="change()">The images</button>
<canvas width="300" height="300" id="canvas"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script>
<script>
// instantiate canvas
canvas = new fabric.Canvas('canvas')
// Create a picture object
fabric.Image.fromURL('.. /.. /images/Agumon.png'.oImg= > {
/ / text
const text = new fabric.Text('Group without cache', {
fontSize: 14.top: 50
})
/ / create a group
const group = new fabric.Group([oImg, text], {
objectCaching: false // No cache!!
})
// Add the group to the canvas
canvas.add(group)
})
// Replace the image event
function change() {
/ / access group
const group = canvas.getObjects()[0]
// Get the image
const img = group.getObjects().find(item= > {
// Determine image elements by isType because there are two elements in the group (one image, one text)
return item.isType('image')})// Find the image and replace it
img.setSrc('.. /.. /images/Bhikkhu.png'.() = > {
// Refresh the canvas after replacing the image
canvas.renderAll()
})
}
</script>
Copy the code
In this case, objectCaching: false should be declared, especially when creating a group.
Scenario 3: Modifying images within the group (cached)
If the Group (Group) is set to cache, you need to change the image in the Group (Group).
Here’s how I did it:
- Find the image object and save it to a variable;
- Remove picture objects from a Group (using group.removeWithUpdate);
- To update the image object
src
Point to (useImage.setSrc
); - Put images into groups (using group.addWithUpdate);
- Rerender the Canvas (using canvas.renderAll);
<style>
canvas {
border: 1px solid #ccc;
}
</style>
<button onclick="change()">The images</button>
<canvas width="300" height="300" id="canvas"></canvas>
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script>
<script>
// instantiate canvas
canvas = new fabric.Canvas('canvas')
// Create a picture object
fabric.Image.fromURL('.. /.. /images/Agumon.png'.oImg= > {
/ / text
const text = new fabric.Text('Group without cache', {
fontSize: 14.top: 50
})
/ / create a group
const group = new fabric.Group([oImg, text])
// Add the group to the canvas
canvas.add(group)
})
// Replace the image event
function change() {
/ / access group
const group = canvas.getObjects()[0]
// [1] Find the image object and save it to a variable
const img = group.getObjects().find(item= > {
// Determine image elements by isType because there are two elements in the group (one image, one text)
return item.isType('image')})// [2] Delete the image object in the group
group.removeWithUpdate(img)
// [3] Update the 'SRC' direction of the image object
img.setSrc('.. /.. /images/Bhikkhu.png'.() = > {
// [4] Put the pictures into groups
group.addWithUpdate(img)
[5] re-render the canvas
canvas.renderAll()
})
}
</script>
Copy the code
Following this example can achieve the goal, but always feel uncomfortable.
If you have a better idea to share, discuss learning together.
If you also need to change images in your project, but not in the above 3 scenarios, please leave a comment and I will try to solve it.
Code warehouse
The native implementation changes the image
Images are changed using the Fabric implementation in Vue3
More recommended
Fabric.js from Getting Started to Mastering
Fabric.js implement Gradient effects, including radial Gradient radial
Fabric.js Custom Right-click menu