Fabric.js three methods of changing pictures (including changing pictures in the group and caching)

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:

  1. Find the picture object and save it to a variable;
  2. Delete picture objects within a group (using Group.removeWithUpdate );
  3. Update src pointing of picture object (use) Image.setSrc );
  4. Put pictures in groups (use Group.addWithUpdate );
  5. 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

Change picture in native mode

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!

Keywords: Javascript Front-end html5 Vue.js css

Added by 10legit10quit on Fri, 14 Jan 2022 21:58:17 +0200