Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should 'stopPropagation' prevent canvas from receiving mouse events on Fabricjs objects?

This is a pretty simple question but I can't seem to find an answer.

I have a fabricjs canvas instance with a mouse eventListener attached. I also have a bunch of objects with mouse eventListeners. I do not want mouse events on the objects to get passed through to the canvas. stopPropagation and/or stopImmediatePropagation don't stop the events.

Am I using these methods wrong? Or is there a Fabricjs way to handle this?


Method on a class wrapping a Fabricjs canvas instance

this.canvas.on("mouse:down", this.handleMouseDown);

Method on a Fabricjs subclass:

testMouseDownHandler: function (event) {            
        event.e.stopPropagation();
        event.e.stopImmediatePropagation();
        event.e.preventDefault();
        if (event.e.shiftKey) {
            this.canvas.setActiveObject(this);
        }
    },
like image 833
spring Avatar asked Nov 08 '22 02:11

spring


1 Answers

As @traktor53 said in his comment there is no such thing as bubbling on a canvas object. In Konva.js they actually added their own event handling on object level where bubbling is simulated exactly like how you would expect in a normal DOM (more on that great feature of Konva in the docs for Konva.js here: https://konvajs.org/docs/events/Cancel_Propagation.html).

As far as I know it doesn't work like that for Fabric.js, but that doesn't mean you cannot prevent the execution of the event handler of the canvas when clicking on an object.

The main issue is that the canvas event fires before the object event meaning when you try to prevent "bubbling" inside the event handler of the object you are too late (in that sense it is indeed not "bubbling" towards the canvas).

I prevent the canvas event from executing simply by ignoring all canvas events that do have a target, it means it will only run when we clicked on nothing else but the canvas:

canvas.on('mouse:down', (event) => {
    if(event.target !== null){
        //Ignore this event, we are clicking on an object (event.target is clicked object)
        return;
    }
    //... your canvas event handling code...
}

object.on('mousedown', (event) => {
    //... your object event handling code...
    let object = event.target;
}

Find all the other event names here in the docs: http://fabricjs.com/events

Hope this is helpful. If there are other (better solutions) please comment.

like image 122
Wilt Avatar answered Nov 14 '22 22:11

Wilt