konvajs / konva

Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.
http://konvajs.org/
Other
11.72k stars 934 forks source link

getIntersection() ignores nodes with listening = false #1789

Closed mneveroff closed 4 months ago

mneveroff commented 4 months ago

Hey Anton, a pleasure to be finally using your lib, having a blast so far!

Ran into a case that, whilst seems to be intentional, might benefit from more docs or perhaps a change of approach?

Presently, getIntersection() ignores the nodes that aren't visible or have listening set to false: https://github.com/konvajs/konva/blob/00997bc22587ec24cf24bec579afe4b8754e5be3/src/Layer.ts#L322-L324

Whilst it might make perfect sense from implementation standpoint (hit graph and all that), it would be amazing to be able to still get those intersections via a parameter or some other way i.e. getIntersection({notListening: true}).

Alternatively, it would be amazing to get this behaviour documented in getIntersection and listening docs and API.

A bit about my use case. I have the Stage overlaying another canvas, which I by default use to process most of user interactions, but I use Konva to overlay certain graphical elements. I use pointerEvents: none if there isn't a Konva shape under pointer. This works well for the most part, but if I want to "preview" a Konva shape at pointer whilst still passing events to the canvas "below" and I set listening: false, I now can't handle specific events (i.e. click) with that Konva shape. Alternatively, having this issue addressed with an "allow list" approach to event listeners would be amazing as well. Then I'd be able to disable all events for that node apart from the click that I want to handle.

P.S. Since I'm using konva-react I can't exactly set a single on() handler with all events on the node, and specifying many props for the component to cancel propagation with only one to handle it would be rather verbose.

lavrton commented 4 months ago

I updated docs with that note.

I am not sure if I want to overwrite the behavior with something like this getIntersection({notListening: true}).

I see two solutions:

  1. Temporary set listening: true on nodes to do hit detection (may require layer redraw).
  2. Or do intersection calculation manually with some math. node.getClientRect() function may help.
mneveroff commented 4 months ago

Thanks for a swift response and a fix! Yeah, I get that modifying that behaviour for such small a change might not be desirable. For the time being I refactored my code to use event.detail and handle single/double click interactions through that, the shoutout about node.getClientRect() is neat though.