简体   繁体   中英

D3 disable pan & zoom when scrolling

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
    });

Doc: https://github.com/d3/d3-zoom#zoom_filter

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM