轻轻放大到 D3 地图的中心
Zoom softly into the center of a D3 map
我创建了一个 interactive map。该地图可以通过按钮缩放。这些按钮已经可以使用,但我不喜欢当前的样式。当点击按钮时地图有点晃动时,感觉不友好。我想轻轻地放大到地图的中心。
此处放大代码按钮:
d3.select('#zoomplusbutton').on('click', function () {
ardamap.zoomByFactor(1.3);
});
这里是函数代码,带有奇怪的缩放:
zoomByFactor: function (factor) {
d3.event.preventDefault();
var scale = zoom.scale();
var extent = zoom.scaleExtent();
var newScale = scale * factor;
if (extent[0] <= newScale && newScale <= extent[1]) {
var t = zoom.translate();
var c = [width / 2, height / 2];
zoom
.scale(newScale)
.translate([c[0] + (t[0] - c[0]) / scale * newScale, c[1] + (t[1] - c[1]) / scale * newScale])
.event(g.transition());
}
}
我真的不知道我从哪里得到这个缩放代码了。
那么怎样才能真正柔和地缩放到地图的中心呢?随意更改网站上的 JS 代码。
几个小时后,现在想出了一个 'OK' 解决方案。它不是完美的中心,但最后没有晃动和任何其他不良行为:
zoomButton: function (zoom_in) {
var scale = zoom.scale(),
extent = zoom.scaleExtent(),
translate = zoom.translate(),
x = translate[0], y = translate[1],
factor = zoom_in ? 1.3 : 1/1.3,
target_scale = scale * factor;
if (target_scale === extent[0] || target_scale === extent[1] || target_scale > extent[1] || target_scale < extent[0]) { return false; }
var clamped_target_scale = Math.max(extent[0], Math.min(extent[1], target_scale));
if (clamped_target_scale != target_scale){
target_scale = clamped_target_scale;
factor = target_scale / scale;
}
x = (x - center[0]) * factor + center[0];
y = (y - center[1]) * factor + center[1];
if (zoom_in){
x = x - 500;
}else{
x = x + 500;
}
d3.transition().duration(450).tween("zoom", function () {
var interpolate_scale = d3.interpolate(scale, target_scale),
interpolate_trans = d3.interpolate(translate, [x,y]);
return function (t) {
zoom.scale(interpolate_scale(t))
.translate(interpolate_trans(t));
ardamap.zoomedButton();
};
});
}
这些计算非常有效。这里有两个按钮提升事件:
d3.select('#zoomplusbutton').on('click', function(){
ardamap.zoomButton(true);
});
d3.select('#zoomminusbutton').on('click', function () {
ardamap.zoomButton(false);
});
您也可以在 arda-maps.org 上找到代码更新。如果您已经修复了真正进入当前地图中心的问题,请随时编辑我的答案。我仍然有兴趣改进它!
我创建了一个 interactive map。该地图可以通过按钮缩放。这些按钮已经可以使用,但我不喜欢当前的样式。当点击按钮时地图有点晃动时,感觉不友好。我想轻轻地放大到地图的中心。
此处放大代码按钮:
d3.select('#zoomplusbutton').on('click', function () {
ardamap.zoomByFactor(1.3);
});
这里是函数代码,带有奇怪的缩放:
zoomByFactor: function (factor) {
d3.event.preventDefault();
var scale = zoom.scale();
var extent = zoom.scaleExtent();
var newScale = scale * factor;
if (extent[0] <= newScale && newScale <= extent[1]) {
var t = zoom.translate();
var c = [width / 2, height / 2];
zoom
.scale(newScale)
.translate([c[0] + (t[0] - c[0]) / scale * newScale, c[1] + (t[1] - c[1]) / scale * newScale])
.event(g.transition());
}
}
我真的不知道我从哪里得到这个缩放代码了。
那么怎样才能真正柔和地缩放到地图的中心呢?随意更改网站上的 JS 代码。
几个小时后,现在想出了一个 'OK' 解决方案。它不是完美的中心,但最后没有晃动和任何其他不良行为:
zoomButton: function (zoom_in) {
var scale = zoom.scale(),
extent = zoom.scaleExtent(),
translate = zoom.translate(),
x = translate[0], y = translate[1],
factor = zoom_in ? 1.3 : 1/1.3,
target_scale = scale * factor;
if (target_scale === extent[0] || target_scale === extent[1] || target_scale > extent[1] || target_scale < extent[0]) { return false; }
var clamped_target_scale = Math.max(extent[0], Math.min(extent[1], target_scale));
if (clamped_target_scale != target_scale){
target_scale = clamped_target_scale;
factor = target_scale / scale;
}
x = (x - center[0]) * factor + center[0];
y = (y - center[1]) * factor + center[1];
if (zoom_in){
x = x - 500;
}else{
x = x + 500;
}
d3.transition().duration(450).tween("zoom", function () {
var interpolate_scale = d3.interpolate(scale, target_scale),
interpolate_trans = d3.interpolate(translate, [x,y]);
return function (t) {
zoom.scale(interpolate_scale(t))
.translate(interpolate_trans(t));
ardamap.zoomedButton();
};
});
}
这些计算非常有效。这里有两个按钮提升事件:
d3.select('#zoomplusbutton').on('click', function(){
ardamap.zoomButton(true);
});
d3.select('#zoomminusbutton').on('click', function () {
ardamap.zoomButton(false);
});
您也可以在 arda-maps.org 上找到代码更新。如果您已经修复了真正进入当前地图中心的问题,请随时编辑我的答案。我仍然有兴趣改进它!