[Vuejs]-Fabric JS Canvas loses editability and resizability when assigned to Vue data attribute

0👍

After some trial and error, here’s how I manage to get Vue3 working with a Fabric.js canvas.

  1. In your component’s setup script, create a variable called canvas and assign it a value of null.

  2. In the mounted() lifecycle hook setup the canvas.

  3. You can now use this.canvas in your method functions when you need to interact with your canvas.

    <script>
    import { fabric } from 'fabric';
    
    export default {
    setup() {
      let canvas = null;
    
      return {
       canvas
      }
     },
     mounted() {
      const fabricRef = this.$refs.canvas;
      this.canvas = new fabric.Canvas(fabricRef, 
      { 
       width: 800, 
       height: 800
      })
     },
     methods: {
       addText() {
        const textbox = new fabric.Textbox('Lorum ipsum dolor sit amet',    {
        left: 50,
        top: 50,
        width: 150,
        fontSize: 20,
         });
        this.canvas.add(textbox).setActiveObject(textbox);
        }
      }
    }
    
    </script>
    

Why this approach?

From what I’ve observed, if I created a data property to hold my canvas element, then the elements I add to my canvas are not editable:

Does not seem to work:

<script>
// ...
 data() {
 return {
  canvas: null;
}
}

// ...
</script>

0👍

When using Fabricjs and vue 3 you can use "markRaw" when adding objects to the canvas. That will allow you to use the reactivity system and still add objects to the canvas that .

<script>
import { fabric } from 'fabric';
import { markRaw } from 'vue'; 

export default {
setup() {
  let canvas = null;

  return {
   canvas
  }
 },
 mounted() {
  const fabricRef = this.$refs.canvas;
  this.canvas = new fabric.Canvas(fabricRef, 
  { 
   width: 800, 
   height: 800
  })
 },
 methods: {
   addText() {
    const textbox = new fabric.Textbox('Lorum ipsum dolor sit amet',    {
    left: 50,
    top: 50,
    width: 150,
    fontSize: 20,
     });
    this.canvas.add(markRaw(textbox)).setActiveObject(textbox);
    }
  }
}

</script>

Leave a comment