D3.js - how to add a zoom button with default zoom mode for a wheeled mouse

So I ended up with a mouse-scaled world map using the default d3.behavior.zoom () and constraints to allow the map to be completely dragged out of the page. It was a pain to work, but now it works.

Now my problem is that this project also requires the useless + and - zoom buttons in the interface, and I can't find an example depicting both types of zoom. It's either mouse scaling or just crappy button scaling.

I tried just calling zoom.scale (newScale); but doesn't update anything. I seem to be on the right track as in the console you can see that the scale is updated but it is not updating and when I zoom in with the mouse it suddenly goes to the scale that was determined with the button. But it seems to me I also need to update the translation, and I'm not sure how to get how to center the map and calculate the translation needed to zoom in.

I also need to know how to update the projection after calling zoom.scale (newScale); if that's the way to do it.

I made a simplified demo with a zoom button clearly not working right now. http://bl.ocks.org/jfmmm/f5c62bc056e557b80447

Thank!

edit: So close, now it is getting closer to the center of the map because I am using the same calculation I used to calculate the middle of the screen, but with a new scale. The problem is that I want it to zoom in on the object in the middle of the screen, not always in the center of the map.

function zoomBtn(action) {
    var currentZoom = zoom.scale();

    if( action == 'in' ){
        if(currentZoom < options.maxZoomLevel){
            var newScale = Math.floor(currentZoom) + 1;

            var b = path.bounds(mapFeatures);
            var t = [(width - newScale * (b[1][0] + b[0][0])) / 2, (height - newScale * (b[1][1] + b[0][1])) / 2];

            zoom.scale(newScale)
                .translate(t)
                .event(svg);
        }
    }else{
        if(currentZoom > options.minZoomLevel){
            var newScale = Math.floor(currentZoom) - 1;

            var b = path.bounds(mapFeatures);
            var t = [(width - newScale * (b[1][0] + b[0][0])) / 2, (height - newScale * (b[1][1] + b[0][1])) / 2];

            zoom.scale(newScale)
                .translate(t)
                .event(svg);
        }
    }
}

      

I'll update my example in min.

+3


source to share


1 answer


The math for scaling to the center of the screen rather than the top left corner or 0lat / 0lon is pretty tricky to get right. I copy it from the example Wil Linssen and adapting it to Mike Bostock Pan card, and I of Zoom . It's important to note that this example uses SVG transforms to re-render the map, not re-render the projection. There are several ways the buttons work:

  • Zoom buttons I - pressing the button leads to a transition to a new view. Holding down the button does not restart the transition.

  • Zoom Buttons II - Pressing and holding the button will immediately update the new view, every 40ms. This leads to unpleasant jumps, especially when the button is pressed repeatedly.

  • Zoom buttons III are 100ms transitions that continue until the button is no longer saved or the extent scaled. Control logic prevents unwanted instant panning. This is the one to use.



Again, getting the details right is tricky, so I provide complete examples. But okay, the underlying logic makes sense. You zero out the vector, stretch it, and discard it:

x = (x - center[0]) * factor + center[0];
y = (y - center[1]) * factor + center[1];

      

+7


source







All Articles