-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Event propagation to canvas #1388
Comments
I agree that it is a tricky and painful problem but great sum up as always. Solution 1. seems the most promising for me. Solution 4. is more-or-less an implementation variant of it to avoid rewriting |
Opting out of specific events ( I feel like users need to be able to cancel specific interactions instead. More thinking needed... |
Following the refactor of Also, the CSS Grid layout on If we did this for the floating toolbar, then registering For elements that need to let some events through, then |
Is your feature request related to a problem?
Currently,
useCanvasEvents
registers its event handlers on the WebGLcanvas
. As a result, any element positioned on top of the canvas (viaHtml
,SvgElement
,FloatingControl
, etc.) intercepts every event before it can reach thecanvas
element, thus preventing interaction (zoom, pan, etc.). To work around this and let events reach the canvas, we usepointer-events: none
on every overlayaing element.The problem arises with interactive overlaying elements - e.g. a resize handle on an SVG ROI; the ROI itself, to be able to move it around, etc. Currently, we use
pointer-events: auto
to re-enable intercepting events on specific interactive elements, but the downside is that it then re-intercepts every event! There's no way to fine-grain which events to propagate and which to stop -- it's all or nothing.An example of why this is problematic: if we want a ROI to be draggable, then there's no way to let through wheel events so users can still zoom on the visualisation underneath.
Requested solution or feature
useCanvasEvents
could register its event handlers on.r3fRoot
instead ofcanvas
in order to take advantage of event bubbling.The upside of this solution is its simplicity — we don’t try to “catch” and re-fire events or anything like that, and we don’t need to set
pointer-events: none
on every overlaying element. The downside is that it's an opt-out-only solution: every event bubbles by default, so now we need to stop events that we don't want to let through to the canvas.For instance, in this configuration, pressing down on the reset zoom button in the floating toolbar and then dragging the cursor away would pan the visualization. In this case, I'd see a few ways to "opt out" to prevent the pan:
onPointerDown={evt => evt.stopPropagation()}
on the reset zoom button.pointerdown
to start, but this may not be the case in the future or with custom interactions); 2) if users implement their own floating controls, they have to remember to stop events themselves; 3) users have to do this for every element they want to make interactive.div
wrapper insideFloatingControl
and stop events there.useCanvasEvents
's event handlers, detect if the target of the event is abutton
and stop processing the event if that’s the case.rect
.useCanvasEvents
's event handlers, if the target of the event has a specific attribute, likedata-stop-propagation="pointerdown wheel"
, don’t process any of the events listed. Conversely, if relevant, do process the events listed indata-allow-propagation
, disregarding other rules like the one from the previous bullet point.I think bullet point 4 is the most promising, as it's the most versatile solution.
data-stop-propagation
is generic-enough to cover all cases.Bullet 3 could also be beneficial, but less so since most interactive elements other than floating controls are likely to be SVG elements — it also increases the complexity, requiring an additional
data-allow-propagation
for full control.Alternatives you've considered
Catching events on overlaying elements and re-firing them on the
canvas
. Similar opt-in/opt-out challenges as above apply, though.The text was updated successfully, but these errors were encountered: