Animating circles along multiple paths

时光怂恿深爱的人放手 提交于 2021-02-10 20:45:28

问题


I am trying to create an animation where circles are being animated on multiple paths.

I am able to get the animation I want for one of the paths but am not sure why the circles are only animating on that particular path, instead of being distributed according to the path they belong.

The full code can be found on my bl.ocks page: https://bl.ocks.org/JulienAssouline/4a11b54fc68c3255a85b31f34e171649

This is the main part of it

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 + ")";
          }
        }
    }

Basically, I followed this https://bl.ocks.org/mbostock/1705868 example to get the point-along-path interpolation, but am having trouble adapting it to get the same effect on multiple lines.

I also tried adding .attr("cx", function(d){ return d.experience} to the circles but that didn't work.


回答1:


You're always passing the same path (the first one) to the translateAlong function:

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

You have to pass different paths to the translateAlong function. There are different ways for doing that (I don't know which one you want), one of those is:

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

In this approach, the indices of the circles go from 0 to the data array length minus 1. So, since path.nodes() is an array of elements, it's selecting different ones by their indices.

Here is the updated bl.ocks: https://bl.ocks.org/anonymous/f54345ed04e1a66b7cff3ebeef271428/76fc9fbaeed5dfa867fdd57b24c6451346852568

PS: regarding optimisation, you don't need to draw several paths at the same position! Right now you have dozens of paths which are exactly the same. Just draw the different paths (in your case, only 3).



来源:https://stackoverflow.com/questions/47724173/animating-circles-along-multiple-paths

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