缩放地图时D3js Geo取消缩放元素
D3js Geo unzoom element when zoom map
我有一个用 topojson.js 构建的 D3js 地图。
var projection = d3.geo.mercator();
一切正常,但我正在寻找一种我无法实现的效果。缩放地图时,我希望它上面的图钉按比例缩小,但如果我按比例缩小,我需要重新计算它们的坐标,但我找不到这样做的公式。
缩放处理程序
scale = d3.event.scale;
if (scale >= 1) {
main.attr("transform", "translate(" + d3.event.translate + ")
scale(" + d3.event.scale + ")");
}
else {
main.attr("transform", "translate(" + d3.event.translate + ")scale(1)");
}
//43x49 is the size initial pine size when scale = 1
var pins = main.select("#pins").selectAll("g").select("image")
.attr("width", function () {
return 43 - (43 * (scale - 1));
})
.attr("height", function () {
return 49 - (49 * (scale - 1));
})
.attr("x", function () {
//Calculate new image coordinates;
})
.attr("y", function () {
//Calculate new image coordinates;
});
我的问题是:如何根据新比例计算 x 和 y?
希望我说的够清楚了。
感谢您的帮助
编辑:
初始引脚坐标的计算:
"translate(" + (projection([d.lon, d.lat])[0] - 20) + ","
+ (projection([d.lon, d.lat])[1] - 45) + ")"
-20 和 -45 使针尖正好在目标上。
您需要 "counter-scale" 引脚,即 main
缩放 up/down 您需要在相反方向缩放引脚 down/up。反比例因子是 1/scale
,您应该将其应用于每个包含图钉图像的 <g>
。这使您可以从 <image>
节点中删除当前的宽度和高度计算(因为父级 <g>
的比例会处理它)。
但是,为了使其正常工作,您还需要从 <image>
中删除 x
和 y
属性,并通过反缩放父 <g>
还有。这是必要的,因为如果存在局部偏移(在 <image>
上设置 x 和 y 时的情况),则局部偏移会随着父级 <g>
的缩放而缩放,这会使引脚移动到位置不正确。
所以:
var pinContainers = main.select("#pins").selectAll("g")
.attr("transform", function(d) {
var x = ... // don't know how you calculate x (since you didn't show it)
var y = ... // don't know how you calculate y
var unscale = 1/scale;
return "translate(" + x + " " + y + ") scale(" + unscale + ")";
})
pinContainers.select("image")
.attr("width", 43)
.attr("height", 49)
// you can use non-zero x and y to get the image to scale
// relative to some point other than the top-left of the
// image (such as the tip of the pin)
.attr("x", 0)
.attr("y", 0)
我有一个用 topojson.js 构建的 D3js 地图。
var projection = d3.geo.mercator();
一切正常,但我正在寻找一种我无法实现的效果。缩放地图时,我希望它上面的图钉按比例缩小,但如果我按比例缩小,我需要重新计算它们的坐标,但我找不到这样做的公式。
缩放处理程序
scale = d3.event.scale;
if (scale >= 1) {
main.attr("transform", "translate(" + d3.event.translate + ")
scale(" + d3.event.scale + ")");
}
else {
main.attr("transform", "translate(" + d3.event.translate + ")scale(1)");
}
//43x49 is the size initial pine size when scale = 1
var pins = main.select("#pins").selectAll("g").select("image")
.attr("width", function () {
return 43 - (43 * (scale - 1));
})
.attr("height", function () {
return 49 - (49 * (scale - 1));
})
.attr("x", function () {
//Calculate new image coordinates;
})
.attr("y", function () {
//Calculate new image coordinates;
});
我的问题是:如何根据新比例计算 x 和 y?
希望我说的够清楚了。
感谢您的帮助
编辑:
初始引脚坐标的计算:
"translate(" + (projection([d.lon, d.lat])[0] - 20) + ","
+ (projection([d.lon, d.lat])[1] - 45) + ")"
-20 和 -45 使针尖正好在目标上。
您需要 "counter-scale" 引脚,即 main
缩放 up/down 您需要在相反方向缩放引脚 down/up。反比例因子是 1/scale
,您应该将其应用于每个包含图钉图像的 <g>
。这使您可以从 <image>
节点中删除当前的宽度和高度计算(因为父级 <g>
的比例会处理它)。
但是,为了使其正常工作,您还需要从 <image>
中删除 x
和 y
属性,并通过反缩放父 <g>
还有。这是必要的,因为如果存在局部偏移(在 <image>
上设置 x 和 y 时的情况),则局部偏移会随着父级 <g>
的缩放而缩放,这会使引脚移动到位置不正确。
所以:
var pinContainers = main.select("#pins").selectAll("g")
.attr("transform", function(d) {
var x = ... // don't know how you calculate x (since you didn't show it)
var y = ... // don't know how you calculate y
var unscale = 1/scale;
return "translate(" + x + " " + y + ") scale(" + unscale + ")";
})
pinContainers.select("image")
.attr("width", 43)
.attr("height", 49)
// you can use non-zero x and y to get the image to scale
// relative to some point other than the top-left of the
// image (such as the tip of the pin)
.attr("x", 0)
.attr("y", 0)