[英]How do you change the interpolation for a zoom behavior in d3.js
我正在使用 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>
不幸的是,这并没有表现出我所看到的行为。 (在我的真实版本中,比例 k 使用van Wijk 平滑缩放通过 0 插入)但问题仍然有效。 如果我要更改此缩放行为的插值器,我将如何以及在何处执行此操作? 我曾尝试调用文档似乎建议的 zoomBehavior.interpolate(d3.interpolate),但我收到一条错误消息,指出 zoomBehavior.interpolate 不是函数。
我们遇到了同样的问题,并通过使用interpolate
方法解决了它。 应用于您的代码,它看起来像这样:
zoomBehavior.interpolate(d3.interpolate).scaleExtent([0.5, 10])
.on('zoom', zoomed);
根据http://devdocs.io/d3~4/d3-zoom#zoom_interpolate , d3.interpolate
应用“两个视图之间的直接插值”,而默认值是d3.interpolateZoom
,它应用我们都不想要的“平滑缩放”。
如果没有看到您试图避免的行为,就很难回答这个问题。 您上面的示例代码按预期工作。 也就是说,这是一个完全控制插值器并因此控制转换的示例。 在这里,我将圆圈缩放回scale: 1
但x
和y
位于 svg 的右下方:
<!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>
请注意,您现在可以使用.rho
在d3.interpolateZoom (V2.0.1)自定义曲率你同时缩放和平移量。 默认为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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.