d3:手绘线条的动画效果如何?

时间:2013-12-20 03:14:33

标签: javascript animation d3.js

请参阅this pen了解我想要的工作但是很简陋的版本:一个d3动画,它可以实时模拟一个人正在绘制的线条的路径。

我目前的实施有两个问题:

  1. 这是不稳定的。您可以看到每条路径都显示为一个块,而不是看起来就像是笔在屏幕上移动的路径。一种解决方案是使每个块更小 - 是否还有其他解决方案?

  2. 这是递归的。用setTimeout()递归地调用绘图与d3精神相反。是否有更具声明性的解决方案?也许使用transition()

  3. 的Javascript

    var svg = d3.select("body").append("svg")
                               .attr("width", "100%")
                               .attr("height", "100%");
    
    
    var lineData = d3.range(5,800,15).map(function(x) {
      return {x: x, y: 10 + Math.floor(Math.random()*6)-3}
    });
    
    var lineFunction = d3.svg.line()
                             .x(function(d) { return d.x; })
                             .y(function(d) { return d.y; })
                             .interpolate("basis");
    
    function draw(points) {
    
      var lineGraph = svg.append("path")                            
                         .attr("stroke", "blue")
                         .attr("stroke-width", 1)
                         .attr("fill", "none")
                         .attr("d", lineFunction(points));
    
      if (points.length < lineData.length)
        setTimeout(function(){
          draw(lineData.slice(0,points.length+1));
        }, 50);
    }
    
    draw([]);
    

1 个答案:

答案 0 :(得分:7)

See this simple (and neat) trick使用stroke-dasharray逐步设置路径的绘制动画。这是your code, modified

var lineGraph = svg
  .append("path")
  .attr("stroke", "blue")
  .attr("stroke-width", 1)
  .attr("fill", "none")
  .attr("d", lineFunction(lineData))
  .transition()
  .duration(5000)
  .attrTween("stroke-dasharray", tweenDash)

function tweenDash() {
  var l = this.getTotalLength(),
      i = d3.interpolateString("0," + l, l + "," + l);
  return function(t) { return i(t); };
}