[英]D3.js tweening forward and backward to a specific point
i just started playing around with Tweening in D3 and at start looked easy but now I'm struggling to achive this in my current code: 我刚开始玩D3中的Tweening,开始看起来很简单,但现在我正努力在当前的代码中实现这一点:
(Probably using buttons to control this) (可能使用按钮来控制这个)
This is my code at the moment: https://jsfiddle.net/uozko2bw/2/ 这是我目前的代码: https : //jsfiddle.net/uozko2bw/2/
//The data for our line
var lineData = [
{ "x": 1, "y": 5}, { "x": 20, "y": 20},
{ "x": 40, "y": 10}, { "x": 60, "y": 40},
{ "x": 80, "y": 5}, { "x": 100, "y": 60}];
var lineFunction = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.curve(d3.curveCardinal);
//The SVG Container
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200);
//The line SVG Path we draw
var lineGraph = svgContainer.append("path")
.attr("d", lineFunction(lineData))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
var circle = svgContainer.append("circle")
.attr("r", 5)
.attr("transform", "translate(" + lineData[0].x + "," + lineData[0].y +
")");
transition();
function transition() {
circle.transition()
.duration(10000)
.attrTween("transform", translateAlong(lineGraph.node()))
.each("end", transition);
}
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}
That t
in the interpolator typically goes from 0 to 1: 内插器中的 t
通常从0到1:
The returned interpolator will then be invoked for each frame of the transition, in order, being passed the eased time t, typically in the range [0, 1]. 然后,对于每个转换帧,将调用返回的内插器,以便顺序通过缓和时间t,通常在[0,1]范围内。
Thus, you can simply call another interpolator with t
going from 1 to 0: 因此,您可以简单地调用另一个内插器, t
从1到0:
var p = path.getPointAtLength((1-t) * l);
Here is the demo: 这是演示:
//The data for our line var lineData = [ { "x": 1, "y": 5}, { "x": 20, "y": 20}, { "x": 40, "y": 10}, { "x": 60, "y": 40}, { "x": 80, "y": 5}, { "x": 100, "y": 60}]; var lineFunction = d3.line() .x(function(d) { return dx; }) .y(function(d) { return dy; }) .curve(d3.curveCardinal); //The SVG Container var svgContainer = d3.select("body").append("svg") .attr("width", 200) .attr("height", 200); //The line SVG Path we draw var lineGraph = svgContainer.append("path") .attr("d", lineFunction(lineData)) .attr("stroke", "blue") .attr("stroke-width", 2) .attr("fill", "none"); var circle = svgContainer.append("circle") .attr("r", 5) .attr("transform", "translate(" + lineData[0].x + "," + lineData[0].y + ")"); transition(); /* svgContainer.on("click", function() { transition(); });*/ function transition() { circle.transition() .duration(10000) .attrTween("transform", translateAlong(lineGraph.node())) .on("end", transition2); } function transition2() { circle.transition() .duration(10000) .attrTween("transform", translateAlong2(lineGraph.node())); } function translateAlong(path) { var l = path.getTotalLength(); return function(d, i, a) { return function(t) { var p = path.getPointAtLength(t * l); return "translate(" + px + "," + py + ")"; }; }; } function translateAlong2(path) { var l = path.getTotalLength(); return function(d, i, a) { return function(t) { var p = path.getPointAtLength((1-t) * l); return "translate(" + px + "," + py + ")"; }; }; }
<script src="https://d3js.org/d3.v4.min.js"></script>
PS: In D3 v4, it's .on("end"...
, not each("end"...
. PS:在D3 v4中,它是.on("end"...
,而不是each("end"...
。
PPS: There is a lot of repetition in my solution. PPS:我的解决方案中有很多重复。 I'll let the DRY homework for you. 我会为你做干燥的功课。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.