D3.js - 如何添加缩放按钮与默认的滚轮缩放行为

5
所以我用默认的d3.behavior.zoom()实现了带有鼠标缩放和限制的世界地图,以防止地图被完全拖出页面。这很难实现,但现在已经可以了。
我的问题是,这个项目还需要在界面中添加没用的缩放+和-按钮,而我找不到同时包含两种类型缩放的示例。它要么只有鼠标缩放,要么只有垃圾的按钮缩放。
我尝试简单地调用zoom.scale(newScale);,但它不会更新任何内容。我似乎走在正确的轨道上,因为在控制台中可以看到比例尺已更新,但它不会更新,当我用鼠标缩放时,它突然跳到使用按钮定义的比例尺。但我似乎也需要更新平移,我不确定如何获取地图的中心并计算所需的平移量以进行缩放。
如果这是更新投影的方法,我还需要知道如何在调用zoom.scale(newScale);之后更新投影。
我用缩放按钮制作了一个简化的演示,显然现在不能正常工作。 http://bl.ocks.org/jfmmm/f5c62bc056e557b80447 感谢! 编辑: 现在非常接近了,它会缩放到地图的中心,因为我使用了与计算屏幕中心相同的计算方法,但是采用了新的比例尺。问题在于我希望它缩放到屏幕中间的对象上,而不总是地图中间的国家。
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);
        }
    }
}

我马上更新我的示例。


您可以使用zoom.event(svg)更新投影。请参见https://github.com/mbostock/d3/wiki/Zoom-Behavior#event。 - Jonathan Pullano
那个缩放很好用,谢谢! - jfmmm
现在我的问题是它会缩放到地图的左上角。我该如何设置它缩放到中心?是使用zoom.translate还是zoom.center?我又该如何获取中心位置呢? - jfmmm
mbostock现在有一个关注中心的缩放按钮示例,链接在这里(2015年4月9日):bl.ocks.org/mbostock/7ec977c95910dd026812 - user4534236
1个回答

8
缩放到屏幕中心,而不是向左上角或0lat/0lon缩放的数学公式相当棘手。我从Wil Linssen's example复制它,并将其移植到Mike Bostock的 Map Pan & Zoom I 上。重要的是,该示例使用SVG变换重新呈现地图,而不是不断重新计算投影。您可能希望按钮按以下几种方式工作:
  • 缩放按钮1 - 按下按钮会导致过渡到新视图。长按按钮不会重新启动过渡。

  • 缩放按钮2 - 按住按钮会立即更新新视图,每40ms更新一次。这会导致不愉快的跳跃,特别是在重复点击按钮时。

  • 缩放按钮3 - 100ms链接转换,直到按钮不再按下或达到scaleExtent为止。控制逻辑可以防止任何不良的瞬间平移。这是要使用的。

再次,正确理解细节很棘手,这就是为什么我提供完整示例的原因。但令人满意的是,核心逻辑确实是有意义的。您正在将向量归零,拉伸它,然后取消归零:

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

当我尝试这个时,我得到了“ReferenceError: center未定义”的错误。 - kwoxer
查看示例以了解它的定义。最后两行是摘录。 - mgold
啊,好的,你在最上面声明了它。好的,我没看到,不好意思。 - kwoxer
澄清一下,当设置了viewbox时,中心属性应为viewbox宽度和高度的一半。这对于响应式SVG非常重要。我的viewbox宽度和高度都为4000,因此中心点分别为2000。代码如下:center = [4000 / 2, 4000 / 2] - Ole Henrik Skogstrøm
另外,如果在初始化缩放时翻译svg,则需要将其添加到中心属性中,如下所示:center[0] += startWidthcenter[1] += startHeight - Ole Henrik Skogstrøm
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接