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.71k stars 933 forks source link

Top objects prevent events on the objects below them #238

Closed EugeneSqr closed 7 years ago

EugeneSqr commented 7 years ago

The problem looks similar to this one. However in my case objects listen for different types of events:

Capturing "mousemove" events on the upper rectangle prevents capturing "click" events on the lower rectangle. Please see this jsfiddle for better illustration of the problem.

Expected behavior: "mousemove" events on upper objects should not prevent "click" events on the objects below.

lavrton commented 7 years ago

Capturing "mousemove" events on the upper rectangle prevents capturing "click" events

No. You have no click on lower rectangle because it is UNDER the black rectangle. If you click on black (upper) rectangle there are no events on the lower rectangle. And this is expected behavior.

Clicking on red rectangle works just fine.

EugeneSqr commented 7 years ago

I'm not subscribed on upper (black) rectangle clicks. Why it prevents clicks to pass through to lower layers then? If this is by design, then how the desired behavior can be achieved? I can't disable all events on the black rectangle, some of them are still needed.

lavrton commented 7 years ago

The behavior is exactly the same as for DOM elements and events.

Why it prevents clicks to pass through to lower layers then?

Because you clicked on the top rectangle. It is like papers on a table. If you touch upper one, then you didn't touch lower one. You can disable all events from the top rectangle. So all events will go down to lower rect.

If this is by design, then how the desired behavior can be achieved?

If you need to listen to events on lower rect you can manually check intersection of pointer position and lower rectangle. If they intersect - trigger you click function handler.

EugeneSqr commented 7 years ago

The behavior is exactly the same as for DOM elements and events.

That's right, the problem is that desktop frameworks do it differently, I expected at least a possibility to do something similar here.

Calculating intersections could be a way to go, however in my case all the objects are spread across multiple layers according to this konva performance tip:

One of the things that makes Konva stand out from other canvas libraries is that it enables us to create individual layers, each with their own canvas elements.

Is there a way of calculating intersection between two objects that belong to different layers?

lavrton commented 7 years ago

@EugeneSqr hard to say, because I don't see what exactly you want to achieve.

Is there a way of calculating intersection between two objects that belong to different layers?

There is not built-in way to calculate the intersection between OBJECTS. But you can use node.intersects(point) method to find an intersection between an OBJECT and a POINT.

EugeneSqr commented 7 years ago

The real scenario involves swiping instead of "mousemove" events in my example above. One should be able to swipe out all objects from a certain layer (or multiple layers) by applying swipe gesture on any part of the stage. The objects must stay clickable though. I place a transparent rectangle above all the layers and want it to react only on swipe gestures, letting all other events (especially clicks) pass through.

There is not built-in way to calculate the intersection between OBJECTS.

I'm sorry I confused your suggestion with the one in this issue

But you can use node.intersects(point) method to find an intersection between an OBJECT and a POINT.

Sounds like I need to build my own event system. I'm going to give it a try if there is no other option.