d3 / d3-zoom

Pan and zoom SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-zoom
ISC License
501 stars 144 forks source link

Zoom event listeners are passed an incorrect sourceEvent if a programmatic zoom occurs during a user zoom gesture #253

Open yurivish opened 2 years ago

yurivish commented 2 years ago

Programmatic zoom intiated while the user is making a gesture causes the zoom callback to be invoked with the sourceEvent from the preceding user action, rather than an undefined sourceEvent.

I think this is because there is an active Gesture on the element and the following line does not update the event to null or undefined:

https://github.com/d3/d3-zoom/blob/23016d4ac35dd3f85d7696afbc77eb05036faa57/src/zoom.js#L192

which is called indirectly from

https://github.com/d3/d3-zoom/blob/main/src/zoom.js#L85

with an undefined event.


Example: https://observablehq.com/d/11402b3301150892 (see console for stack overflow)

The example notebook tries to perform a programmatic zoom once for every user-initiated zoom, but because the programmatic zoomed callback is invoked with a trusted sourceEvent, this results in infinite recursion.

First noticed here (which now implements a workaround)