我使用d3.js V 4.0在SVG中提供缩放和平移。我正在实现一个重置按钮,让我回到图像的中心。它正在工作,但它使用默认的d3.interpolateZoom,因此图像在过渡期间缩小。我只是希望缩放进行标准插值,但我无法弄清楚如何更改缩放行为的插补器。 这是代码的缩写版本:
var map = document.querySelector('#map');
var everything = d3.select('#everything');
var zoomBehavior = d3.zoom();
zoomBehavior.scaleExtent([0.5, 10])
.on('zoom', zoomed);
d3.select(map).call(zoomBehavior);
function zoomed() {
everything.attr('transform', d3.event.transform);
}
function reset() {
d3.select(this.map)
.transition()
.duration(1000)
.call(zoomBehavior.transform, d3.zoomIdentity);
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.1.0/d3.min.js"></script>
<svg id="map" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="everything">
<circle r="5" cx="50" cy="15"></circle>
</g>
</svg>
<button onclick="reset()">reset</button>
&#13;
不幸的是,这并没有表现出我所看到的行为。 (在我的真实版本中,缩放k使用van Wijk smooth zooming插入0但是问题仍然有效。如果我要为这种缩放行为更改插补器,我将如何以及在哪里这样做?我试过调用文档似乎建议的zoomBehavior.interpolate(d3.interpolate),但是我收到一条错误,指出zoomBehavior.interpolate不是函数。
答案 0 :(得分:1)
如果不看到你试图避免的行为,很难回答这个问题。上面的示例代码按预期工作。也就是说,这是一个完整控制插值器并因此完成转换的例子。在这里,我将圈子缩放回scale: 1
,但{s}向右下方x
和y
:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.js"></script>
</head>
<body>
<svg id="map" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="everything">
<circle r="5" cx="50" cy="15"></circle>
</g>
</svg>
<button onclick="reset()">reset</button>
<script>
var map = d3.select('#map'),
everything = d3.select('#everything');
var zoomBehavior = d3.zoom();
zoomBehavior.scaleExtent([0.5, 10])
.on('zoom', zoomed);
map.call(zoomBehavior);
function zoomed() {
everything.attr('transform', d3.event.transform);
}
function reset() {
d3.select(this.map)
.transition()
.duration(1000)
.tween("custom", function() {
var curZoom = d3.zoomTransform(map.node()),
kInter = d3.interpolate(curZoom.k, 1),
xInter = d3.interpolate(curZoom.x, 240),
yInter = d3.interpolate(curZoom.y, 99);
return function(t) {
var ts = d3.zoomIdentity
.translate(xInter(t), yInter(t))
.scale(kInter(t));
map.call(zoomBehavior.transform, ts);
};
});
}
</script>
</body>
</html>
&#13;
答案 1 :(得分:1)
我们遇到了同样的问题,并使用post2
方法解决了。应用于您的代码,它看起来像这样:
interpolate
根据http://devdocs.io/d3~4/d3-zoom#zoom_interpolate,zoomBehavior.interpolate(d3.interpolate).scaleExtent([0.5, 10])
.on('zoom', zoomed);
应用“两个视图之间的直接插值”,而默认值为d3.interpolate
,应用我们都不想要的“平滑缩放”。
答案 2 :(得分:0)
请注意,您现在可以使用d3.interpolateZoom(v2.0.1)中的.rho
来定制缩放和平移时获得的曲率。默认值为Math.sqrt(2)
,而rho(0)
则为线性插值。
这是设置方法:
let zoomBehavior = d3.zoom()
.interpolate(d3.interpolateZoom.rho(0.9)) // 0.9 for less curvature
.scaleExtent([0.5, 10])
.on('zoom', zoomed);