沿多条路径制作动画圈

时间:2017-12-09 00:48:44

标签: javascript d3.js

我正在尝试创建一个动画,其中圆圈在多个路径上进行动画处理。

我能够为其中一条路径获取我想要的动画,但我不确定为什么圆圈只是在该特定路径上制作动画,而不是根据它们所属的路径进行分配。

完整的代码可以在我的bl.ocks页面找到:https://bl.ocks.org/JulienAssouline/4a11b54fc68c3255a85b31f34e171649

这是它的主要部分

var path = svg.selectAll("path")
      .data(data.filter(function(d){
        return d.From > 2010
      }))
      .enter()
      .append("path")
      .style("stroke", "#832129")
      .attr("class", "arc")
      .attr("d", function(d){
        var To_scale = xScale(d.experience),
            From_scale = xScale(0),
            y = yScale(0),
            dx = To_scale - From_scale,
            dy = y,
            dr = Math.sqrt(dx * dx + dy * dy);
        return "M" + From_scale + " " + y + " A 43 50 0 0 1 " + To_scale + " " + y;
      })
      .style("fill", "none")
      .style("opacity", 0)
      .call(transition)
      .on("mouseover",  function(d){
        var thisClass = d3.select(this).attr("class")
          d3.selectAll(".path").style("opacity", 0.1)
          d3.select(this).style("stroke", "white").style("opacity", 1).style("stroke-width", 2)

        })
        .on("mouseout",  function(d){
          d3.select(this).style("stroke", "#832129").style("opacity", 1)
        })





      function transition(path){
        path.each(function(PathItem, index){
         d3.select(this).transition()
          // .delay(index + 200)
          .duration(index * 5 + 1000)
          .on("start", function(){
            d3.select(this).style("opacity", 1)
          })
          .attrTween("stroke-dasharray", tweenDash)
        })

      }

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

      console.log(data[0])


var circle = svg.selectAll("circle")
    .data(data.filter(function(d){
        return d.From > 2010
      }))
    .enter()
    .append("circle")
    .attr("r", 5)
    .attr("cx", function(d){
      return xScale(d.experience)
    })
    .style("fill", "red")
    .attr("transform", "translate(" + 0 + ")")
    .style("opacity", 0)

transition_circles();

  function transition_circles(){
      circle.each(function(pathItem, index){
      d3.select(this)
      .transition()
      .delay(index * 200)
      .duration(index * 10 + 1000)
      .on("start", function(){
        d3.select(this).style("opacity", 1)
      })
      .on("end",function(){
        d3.select(this).style("opacity", 0)
      })
      .attrTween("transform", translateAlong(path.node(), index))
      })


    }

    function translateAlong(path, index){
     var l = path.getTotalLength();
      return function(d, i , a){
        return function(t){
          var p = path.getPointAtLength(t * l);
          return "translate(" + p.x + "," + p.y + ")";
          }
        }
    }

基本上,我遵循这个https://bl.ocks.org/mbostock/1705868示例来获得逐点插值,但是我很难适应它以在多行上获得相同的效果。

我也尝试将.attr("cx", function(d){ return d.experience}添加到圈子中,但这不起作用。

1 个答案:

答案 0 :(得分:1)

您始终将相同的路径(第一个路径)传递给translateAlong功能:

.attrTween("transform", translateAlong(path.node(), index))
//this is always the first path ---------^

您必须将不同的路径传递给translateAlong函数。有不同的方法(我不知道你想要哪一个),其中一个是:

.attrTween("transform", translateAlong(path.nodes()[index], index))

在这种方法中,圆的索引从0到数据数组长度减去1.因此,由于path.nodes()是一个元素数组,所以它们通过它们的索引选择不同的元素。 / p>

以下是更新的bl.ocks:https://bl.ocks.org/anonymous/f54345ed04e1a66b7cff3ebeef271428/76fc9fbaeed5dfa867fdd57b24c6451346852568

PS:关于优化,您不需要在同一位置绘制多条路径!现在你有几十条完全相同的路径。只绘制不同的路径(在您的情况下,只有3个)。