4

因此,我使用默认的 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);
        }
    }
}

我会在一分钟内更新我的示例。

4

1 回答 1

8

放大到屏幕中心而不是左上角或 0lat/0lon 的数学计算是相当棘手的。我从Wil Linssen 的示例中复制它,并将其移植到 Mike Bostock 的Map Pan & Zoom I中。重要的是,该示例使用 SVG 变换来重新渲染地图,而不是不断地重新计算投影。您可能希望按钮工作的几种方式:

  • 缩放按钮 I - 按下按钮会导致转换到新视图。按住按钮不会重新开始转换。

  • 缩放按钮 II - 按住按钮会立即更新新视图,每 40 毫秒。这会导致令人不快的跳跃,尤其是在反复单击按钮时。

  • 缩放按钮 III - 100 毫秒的链式转换,一直持续到不再按住按钮或达到 scaleExtent 为止。控制逻辑防止任何不需要的即时平移。这是要使用的。

同样,正确获取细节是很棘手的,这就是我提供完整示例的原因。但令人满意的是,核心逻辑确实是有道理的。您正在对向量进行归零、拉伸和取消归零:

x = (x - center[0]) * factor + center[0];
y = (y - center[1]) * factor + center[1];
于 2014-11-26T21:33:38.293 回答