如何在d3.js中为路径上的多个圆圈制作动画?

时间:2016-09-03 15:26:36

标签: javascript jquery d3.js

我试图将此作为参考https://bl.ocks.org/mbostock/1705868

我想将多个圆圈旋转为点而不是无限旋转的单个圆圈。

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

我最初将路径上的所有必需点绘制为https://jsfiddle.net/tzbd9r1f/2/

我在这里遇到两个问题:

1:当我尝试为所有圆圈设置动画时,我只看到一个圆形动画而不是5个圆圈https://jsfiddle.net/tzbd9r1f/1/

2:如果我尝试为所有5个圆圈调用结束过渡,我会得到最大的堆叠错误,以防止它像这里一样无限旋转https://jsfiddle.net/tzbd9r1f/3/

请指导。

1 个答案:

答案 0 :(得分:1)

代码中的基本问题是您同时对所有积分应用相同的翻译。实际上你的所有圈子都沿着路径移动,但它们互相覆盖 - 所以你已经完成了任务的主要部分。但是,如果您希望不同的圆圈位于不同的坐标,则必须为它们应用不同的补间。也就是说,即使您为每个圆圈计算startPoints不同,也不会在动画后期使用它,因此所有圆圈都在一起移动。

我通过将点的索引添加为translateAlong函数的新参数,并使用一些基本数学计算圆的位置来解决此问题,因此它变为:

function translateAlong(path,ind) {
  var l = path.getTotalLength();
  return function(i) {
    return function(t) {
      var p = path.getPointAtLength(((t+ind/5)%1)* l);
      return "translate(" + p.x + "," + p.y + ")";//Move marker
    }
  }
}

当然这也需要更改函数调用,如果你还想要无限循环,那么这里有一个小问题,因为当我们将函数作为参数传递时,它需要一个{{ 3}}

总而言之,transitionAll以下列方式进行了更改(我还添加了线性缓动以使圆圈具有更加规则的移动速度):

function transitionAll(marker,ind){
  console.log(marker);
  marker.transition()
    .duration(7500).ease("linear")
    .attrTween("transform", translateAlong(path.node(),ind))
    .each("end", partial(transitionAll,marker,ind));// infinite loop*/

新的部分功能是从我链接的帖子中复制的:

function partial(func /*, 0..n args */) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function() {
    var allArguments = args.concat(Array.prototype.slice.call(arguments));
    return func.apply(this, allArguments);
  };
}              

另外,请勿忘记更改transitionAllforEach功能的呼叫 - 循环startPoints