How to animate a path along with its points in d3

匿名 (未验证) 提交于 2019-12-03 01:34:02

问题:

I am trying to animate a set of points along with a path. Essentially I want to draw the path as the point appears, is there a way for them to have the same delay? I tried doing some calculations but the points seem to be plotted before the line gets to it. Here is a fiddle:

http://jsfiddle.net/Y62Hq/1/

And an excerpt of my code:

var totalLength = path.node().getTotalLength();  var duration = 7000; var interval = Math.round(duration/data.length);  path     .attr("stroke-dasharray", totalLength + " " + totalLength)     .attr("stroke-dashoffset", totalLength)     .transition()     .duration(duration)     .ease("linear")     .attr("stroke-dashoffset", 0);   var circles = svg.selectAll("circle")     .data(data)     .enter()     .append("circle")     .attr("fill", "blue");      circles     .transition()     .delay(function (d, i) { return i * interval;})     .ease("linear")     .attr({         cx: function (d) { return yearScale(d.year); },         cy: function (d) { return window.innerHeight - numberScale(d.number)},         r: 4,         fill: "blue",         // /stroke: "#78B446",         "stroke-width": 4     });

回答1:

Hmm, intriguing. The problem is that not all of your line segments are the same length. While they all cover the same x distance, the y distance is different. Therefore, the amount of time the different line segments take to reach the next point differs. So you can't use a constant delay.

One way of doing this is to add and measure the different line segments, record their lengths and base the delay of the circles appearing on those lengths relative to the total length and the total duration.

var segments = [0]; for(var i = 1; i < data.length; i++) {   var tmp = svg.append("path")     .datum([data[i-1], data[i]])     .attr("d", line);   segments.push(segments[i-1] + tmp.node().getTotalLength());   tmp.remove(); }

This code adds each line segment (from the first point to the second, second to third and so on), measures its length and removes it immediately afterwards. The result is accumulated in the array segments, which gives the length of the total path up to this point (this is needed for the delay). This is why the previous length is added to the current length.

Then all you need to do to compute the delay for the points is

.delay(function (d, i) { return segments[i]*duration/totalLength;})

Complete demo here. This should work for any number of points/type of line.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!