I've rendered a d3 map that has pan and zoom enabled, but when scrolling down the viewport either on desktop or mobile, the window gets stuck zooming in the map.
Is there a way to temporarily disable d3.zoom, while the window is scrolling?
I've seen ways of toggling the zoom/pan using a button as seen here: http://jsfiddle.net/0xncswrk/ , but I wanted to know if it's possible without having to add a button. Here's my current zoom logic.
Thanks!
this.zoom = d3.zoom()
.scaleExtent([1, 8])
.on('zoom', () => {
this.svg.attr('transform', d3.event.transform);
});
this.svg = d3.select(this.el).append('svg')
.attr('width', '100%')
.attr('height', this.height)
.attr('class', 'bubble-map__svg-us')
.call(this.zoom)
.append('g');
EDIT: Wow old answer but never saw your comment. Sorry about that. Yeah sorry I forgot to consider mobile zooming.
In the documentation, perhaps this is new, but they recommend having more granular control of what zoom you allow by using zoom.filter . For touch related events, they also support zoom.touchable .
As specified in the d3-zoom
documentation
To disable just wheel-driven zooming (say to not interfere with native scrolling), you can remove the zoom behavior's wheel event listener after applying the zoom behavior to the selection:
selection .call(zoom) .on("wheel.zoom", null);
You can also consider just setting the scaleExtent
to be [1,1]
especially if it's just temporary so it locks the zoom to only one possible scale but preferably you opt for what the documentation says :P
Got here because I was dealing with a similar problem. Perhaps for anyone coming after this, a simple way to deal with this might be to use the filter()
method that a zoom()
instance provides. That will allow you to toggle between applying or ignoring zoom events altogether. It works a little better than temporarily setting null
to watchers because - at least in my experience - the events then still get recorded and stacked. As a consequence, you would zoom in or out in unexpected leaps once you re-enabled the handler. The filter actually really ignores what's going on, it seems. To implement:
let isZooming = true; // Use controls to set to true or false
zoom()
// Make sure we only apply zoom events if zooming is enabled by the user
.filter(() => isZooming)
.on('zoom', event => {
// Specify whatever you want to do with the event
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.