FabricJS Alternating between canvas elements?

Let’s say I have two canvas elements:

<canvas id="c1" width="400" height="300"></canvas>
<canvas id="c2" width="400" height="300"></canvas>
<canvas id="c3" width="400" height="300"></canvas>

From looking at the docs, it tells me that I can use this to convert the canvas into a FabricJS canvas.

var c = new fabric.Canvas('c1', {
    preserveObjectStacking: true,
    isDrawingMode: false
});

Now, if I wanted to do something with this new canvas, adding a circle for instance, I could use this function:

function AddCircle() {
  var object = new fabric.Circle({
      radius: 15,
      fill: 'blue',
      left: 100,
      top: 100
  });
  c.add(object);
}

Now, this is all well and good for c1 but c2 and c3 won’t do anything because it’s never being initialized. So is it possible to alternate between FabricJS canvas elements?

I’d like the functionality to be similar to activeCanvas.add(object) instead of just c.add(object).

Before you respond, please note that I’m well aware that I could just use the same method for the c2 element, but I’d like to alternate between canvas elements instead as I have something planned for that.

2 thoughts on “FabricJS Alternating between canvas elements?”

  1. Melciar‘s answer is a fantastic explanation, and I recommend you read it, but I’d like to build on one thing he said. You can initialize them like this:

    var options = { preserveObjectStacking: true, isDrawingMode: false };
    var c1 = new fabric.Canvas('c1', options),
        c2 = new fabric.Canvas('c2', options),
        c3 = new fabric.Canvas('c3', options),
        allCanvas = [c1, c2, c3];
    

    And now you can modify them all, or individually. If you want to modify them all simultaniously, you can do this:

    allCanvas.forEach(function(item,index){
          var myCircle = new fabric.Circle({
              radius: 15,
              fill: 'blue',
              left: 100,
              top: 100
          });
          item.add(myCircle);
    });
    

    and, of course, you can still modify them individually as per melchair‘s fantastic explanation:

    c1.add(object1);
    c2.add(object2);
    c3.add(object3);
    
    Reply
  2. I’m not entirely sure what you mean by alternating between canvas elements, but here’s my recommendation.

    Initialize all canvases first:

    var options = { preserveObjectStacking: true, isDrawingMode: false };
    var c1 = new fabric.Canvas('c1', options),
        c2 = new fabric.Canvas('c2', options),
        c3 = new fabric.Canvas('c3', options);
    

    Reference the appropriate canvas when performing a Fabric actions:

    c1.add(object1);
    c2.add(object2);
    c3.add(object3);
    

    FabricJS doesn’t have an inbuilt activeCanvas variable when working with multiple canvases, but you can achieve that using events.

    //declare global activeCanvas variable
    var activeCanvas;
    
    //create function for updating activeCanvas variable
    function setActiveCanvas(canvas) {
       activeCanvas = canvas;
    }
    
    //call function to update the activeCanvas variable when the mouse enters any canvas
    c1.on('mouse:over', setActiveCanvas(this));
    c2.on('mouse:over', setActiveCanvas(this));
    c3.on('mouse:over', setActiveCanvas(this));
    

    Now your activeCanvas variable will always refer to the last canvas your mouse entered. Obviously using the mouse:over event won’t work if you want to support touch devices so you may want to choose another event that best fits your project.

    Now you can modify your AddCircle() function to refer to the activeCanvas.

    function AddCircle() {
      var object = new fabric.Circle({
          radius: 15,
          fill: 'blue',
          left: 100,
          top: 100
      });
      activeCanvas.add(object);
    }
    
    Reply

Leave a Comment