silx-kit / h5web

React components for data visualization and exploration
https://h5web.panosc.eu/
MIT License
183 stars 18 forks source link

Allow interacting with canvas through other interactive elements #1473

Closed axelboc closed 1 year ago

axelboc commented 1 year ago

Fix #1388. As discussed in the issue, I take advantage of event bubbling by listening for "canvas events" on canvasWrapper instead of on the canvas itself.

Property pointer-events: none has to remain on canvasWrapper for the stacking order to work, so this part doesn't change: any element that needs to respond to pointer events (hover, click, drag, etc.) must set pointer-events back to auto.

However, from now on, children of canvasWrapper with pointer-events: auto no longer "block" events by default. Events are allowed to bubble up to canvasWrapper, where they may contribute to canvas interactions (zoom, pan, select-to-zoom, etc.)

To prevent a canvas interaction from occurring while interacting with an element (like an annotation), consumers must manually listen for the relevant events and stop their propagation explicitly with evt.stopPropagation(). We expect that in most cases, stopping the propagation of pointerdown events should suffice, since this event controls the beginning of all click-and-drag interactions (pan, select-to-zoom, etc.)

The only place where this new behaviour can be observed currently is on the SvgElement story. One of the rectangles is hoverable; using the wheel to zoom or clicking-and-dragging while hovering the rectangle used to have no effect -- now the canvas zooms and pans as expected.

I'm opening this PR as draft, as I'm planning to write a few more stories to test and demonstrate how to make elements interactive -- maybe even a dedicated documentation page.

axelboc commented 1 year ago

I'm opening this PR as draft, as I'm planning to write a few more stories to test and demonstrate how to make elements interactive -- maybe even a dedicated documentation page.

Change of plan: I'm currently working on a useDrag hook (simpler and more adapted to our use case than the one in @visx/drag) which has so far enabled me to make an SVG circle draggable with very little consumer code. This also allowed me to confirm that the new event bubbling model proposed in this PR works as expected and does not interfere with the drag interaction. useDrag will probably simplify the way some interactions are implemented, like SelectionTool, so I'm going to postpone writing more in-depth documentation for now.