Open vincerubinetti opened 10 months ago
Is this maybe linked to note 8 of the README (introduced here)?
No, that is about ignoring events when trying to go beyond the scaleExtent
while currently within it, i.e. trying to zoom in above the upper scale limit, or zoom out below the lower scale limit. This is about starting below the lower scale limit and trying to go up to it.
Technically the k
being emitted is clamped to the lower scale limit, but whatever d3-zoom is doing internally to track the progression of zoom isn't working quite right. On every tick of zooming in (one mouse wheel
notch, or one touchmove
event for pinch zoom), the scale should first be brought to within the scaleExtent
, then increased/decreased from there based on the relative "delta k
" since the last tick.
I'll try to decipher the code and find the source of the issue.
I'm not sure this would be considered a bug, but it certainly caught me off guard and took a lot of time to track down. Panning/dragging works fine, the problem is only with zoom. The problem seems to happen with mouse wheel or pinch zoom.
Here's my (relevant) code for a d3 map visualization:
What happened:
While testing on a touch device, I saw that the first pinch zoom on the map did not zoom in, it only panned. On inspection, this is because the
event.transform.k
being emitted was constant (limit
), and not increasing as I pulled my fingers apart. However, after zooming or panning once, the next zoom would work just fine (k
would increase).I eventually figured out that d3-zoom's "internal
k
" was increasing (as opposed to the emittedtransform.k
, clamped toscaleExtent
), but since it starts off at1
by default, andlimit
was a lot higher than that, I simply needed to keep pulling my fingers apart -- like the entire width of my screen -- until the emittedtransform.k
started increasing.So I think the scale isn't truly (internally) getting clamped to the
scaleExtent
until after the first zoom (or pan) completes. I'd expect the transform to be instantiated to values within thescaleExtent
,translateExtent
, etc.The solution to all this, for me, is to manually set the scale to the lower limit, right after initializing zoom and also on the double click reset:
zoom.scaleTo(svg, limit);