Introduction to this article
I listed three in fabric JS to replace the picture.
It also includes the operation of changing pictures in the group.
Environment and version
Chrome browser version: 96.0.4664.45
Fabric.js version: 4.6.0
I developed it in the native environment, and also provided a code developed in Vue3 environment (there is a link at the end of the article).
Hands-On Activities
Next, there are three cases, using two pictures agumon PNG and bhikkhu Png, the picture is in iconfont Found on the website.
If you need to use the pictures of this case, you can get them in the warehouse provided at the end of the text.
Scenario 1: replace src of picture elements
If you are adding an Image object to the canvas, you can use Image.setSrc Set up a new picture before using it Canvas.renderAll Just refresh the canvas.
<style> canvas { border: 1px solid #ccc; } </style> <button onclick="change()">Modify picture</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 picture object fabric.Image.fromURL('../../images/Agumon.png', oImg => { // Add picture objects to canvas canvas.add(oImg) }) // Replace picture event function change() { // Get picture object. Because in this example, there is only one element in the canvas. The first element of the array obtained with getObjects() is the image const img = canvas.getObjects()[0] // Use the setSrc method to change the picture. The second parameter is the callback function. Refresh the canvas in the callback function img.setSrc('../../images/Bhikkhu.png', () => { canvas.renderAll() }) } </script>
The above scenario is the simplest.
If there are multiple graphics and pictures on the canvas, you may need to add some custom attributes to judge when creating pictures.
Use fabric getObjects(). Just search with find ().
find() Is the original method of the array.
Scenario 2: modify pictures in the group (no cache)
By default, the created group has a cache. If there is a cache, it is used Canvas.renderAll() Method does not update the picture.
Therefore, when creating a group, you should declare that you do not cache: Group.objectCaching.
<style> canvas { border: 1px solid #ccc; } </style> <button onclick="change()">Modify picture</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 picture object fabric.Image.fromURL('../../images/Agumon.png', oImg => { // text const text = new fabric.Text('Groups without cache', { fontSize: 14, top: 50 }) // Create group const group = new fabric.Group([oImg, text], { objectCaching: false // Do not cache!!! }) // Add groups to canvas canvas.add(group) }) // Replace picture event function change() { // Get group const group = canvas.getObjects()[0] // Get picture const img = group.getObjects().find(item => { // Judge the picture element by isType, because there are 2 elements (one picture and one text) in the group return item.isType('image') }) // Find the picture and replace it img.setSrc('../../images/Bhikkhu.png', () => { // After replacing the picture, refresh the canvas canvas.renderAll() }) } </script>
This scenario focuses on declaring objectCaching: false when creating a group.
Scenario 3: modify pictures in the group (with cache)
If the group has set a cache, you need to replace the pictures in the group.
My approach is:
- Find the picture object and save it to a variable;
- Delete picture objects within a group (using Group.removeWithUpdate );
- Update src pointing of picture object (use) Image.setSrc );
- Put pictures in groups (use Group.addWithUpdate );
- Re render canvas (using Canvas.renderAll);
<style> canvas { border: 1px solid #ccc; } </style> <button onclick="change()">Modify picture</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 picture object fabric.Image.fromURL('../../images/Agumon.png', oImg => { // text const text = new fabric.Text('Groups without cache', { fontSize: 14, top: 50 }) // Create group const group = new fabric.Group([oImg, text]) // Add groups to canvas canvas.add(group) }) // Replace picture event function change() { // Get group const group = canvas.getObjects()[0] // [1] Find the picture object and save it to a variable const img = group.getObjects().find(item => { // Judge the picture element by isType, because there are 2 elements (one picture and one text) in the group return item.isType('image') }) // [2] Delete picture objects in the group group.removeWithUpdate(img) // [3] Update the 'src' point of the picture object img.setSrc('../../images/Bhikkhu.png', () => { // [4] Put pictures into groups group.addWithUpdate(img) // [5] Re render canvas canvas.renderAll() }) } </script>
According to this example, the goal can be achieved, but I always feel uncomfortable.
If you have better ideas, you can share them and discuss and study together.
If you also need to change the picture in your project, but it is not in the above three scenarios, you can leave a message and I will try to solve it.
Code warehouse
Changing pictures using Fabric implementation in Vue3
More recommendations
Fabric.js from introduction to mastery
Fabric.js to achieve gradient effect, including radial gradient
Fabric.js custom right click menu
This article is composed of blog one article multi posting platform OpenWrite release!