简体   繁体   English

D3.js向前和向后补间到特定点

[英]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,开始看起来很简单,但现在我正努力在当前的代码中实现这一点:

  • Tweening to a specific point, example: from 0,0 to lineData[4] 补间到特定点,例如:从0,0到lineData [4]
  • Tweening back to point 0,0 from lineData[4] 从lineData [4]补间回到0,0点

(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM