如何在d3中为路径及其点设置动画

时间:2014-03-29 18:54:58

标签: d3.js

我正在尝试使用路径为一组点设置动画。基本上我想绘制路径,因为它出现点,有没有办法让它们有相同的延迟?我尝试做了一些计算但是这些点似乎是在线到达它之前绘制的。这是一个小提琴:

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

我的代码的摘录:

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 个答案:

答案 0 :(得分:4)

嗯,有趣。问题是并非所有线段的长度都相同。虽然它们都覆盖相同的x距离,但y距离是不同的。因此,不同线段到达下一点所花费的时间量不同。所以你不能使用恒定的延迟。

这样做的一种方法是添加和测量不同的线段,记录它们的长度,并根据相对于总长度和总持续时间的长度出现圆圈的延迟。

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();
}

此代码添加每个线段(从第一个点到第二个,第二个到第三个,依此类推),测量其长度并在之后立即将其删除。结果累积在数组segments中,它给出了到此时的总路径长度(这是延迟所需的)。这就是将前一个长度添加到当前长度的原因。

然后你需要做的就是计算点的延迟

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

完整演示here。这适用于任意数量的点/线类型。