Skip to content
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

Add flag to zoom behavior to control zooming origin. #616

Closed
wants to merge 1 commit into from

Conversation

@marcneuwirth
Copy link

@marcneuwirth marcneuwirth commented Apr 16, 2012

This allows users to easily disable the event handlers that they don't want, or separate the handling of zoom events into different functions like:

var zoomTranslate = d3.behavior.zoom({
        dblclick: false,
        wheel: false
    })
    .translate(projection.origin())
    .on("zoom", translate);

var zoomScale = d3.behavior.zoom({
        click: false,
        dblclick: false,
        touch: false
    })
    .scale(projection.scale())
    .scaleExtent([100, 800])
    .on("zoom", scale);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(zoomTranslate)
    .call(zoomScale)

This is very useful if you only want the scroll wheel to scale and not translate as well.

@mbostock
Copy link
Member

@mbostock mbostock commented Apr 16, 2012

What about unregistering the events after applying the zoom behavior? For example, you can disable touch and double-click events like so:

var zoom = d3.behavior.zoom()
    .translate(projection.translate())
    .scale(projection.scale())
    .scaleExtent([100, 800])
    .on("zoom", zoommove);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(zoom)
    .on("dblclick.zoom", null)
    .on("touchstart.zoom", null);
@marcneuwirth
Copy link
Author

@marcneuwirth marcneuwirth commented Apr 17, 2012

That will work for cases where you just want to just disable the handler, but not separate handling of the events to different functions.

The real problem is in the way scale is coupled with translate in the mousewheel function. This works fantastically in the basic use case, but makes it impossible to decouple them if you want to zoom straight ahead instead of to the mouse. This is also problem if you want to use zoom on a azimuthal projection, where you want to change the origin and not translate.

Maybe there is a better way to prevent mousewheel from changing translate when necessary

@mbostock
Copy link
Member

@mbostock mbostock commented Apr 17, 2012

It's a bit of a hack, but another option is to have two zoom behaviors on nested elements:

<g class="scale">
  <g class="translate">
  </g>
</g>

Then you bind an inner zoom behavior and an outer zoom behavior, and delete the event listeners as needed. The stop propagation should allow you to use both zoom behaviors independently.

But really I think the simpler solution here is to add a flag to the zoom behavior that says whether mousewheel zooming should zoom on the origin or zoom on the mouse location. I'd support that change. In fact, I implemented exactly that feature for Polymaps; see Wheel.js.

@marcneuwirth
Copy link
Author

@marcneuwirth marcneuwirth commented Apr 17, 2012

I agree, that seems like a much better solution

mbostock added a commit that referenced this pull request Jun 30, 2013
@mbostock
Copy link
Member

@mbostock mbostock commented Jun 30, 2013

Superseded by #1352.

@mbostock mbostock closed this Jun 30, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants