生成多个随机路径并沿路径设置动画圆圈

Generate multiple random paths and animate circles along paths

我正在尝试沿 3 条路径设置 3 个圆圈的动画,这些路径是随机的 generated.Only 正在生成两条路径,并且只有一个圆圈沿其分配的路径设置动画。我试过将数据集和圆配对,这没有效果。

其中一条路径似乎混合了两个数据集以生成一条怪物路径。我该如何阻止呢?我如何让每个圆圈到达其分配的路径?

可能有更优雅的方法来做到这一点。

var w = 2000, h = 2000;

var dataset1 = [] ;                        
    for (var i = 0; i < 5; i++) {            
          var x = Math.floor((Math.random()*900)+1); 
          var y = Math.floor((Math.random()*900)+1);  
          dataset1.push({"x":x, "y":y});
    };

var dataset2 = []  ;                       
    for (var i = 0; i < 4; i++) {            
          var x = Math.floor((Math.random()*700)+1); 
          var y = Math.floor((Math.random()*600)+1);  
          dataset2.push({"x":x, "y":y});
    };

var dataset3 = []  ;                       
    for (var i = 0; i < 3; i++) {            
          var x = Math.floor((Math.random()*800)+1); 
          var y = Math.floor((Math.random()*400)+1);  
          dataset2.push({"x":x, "y":y});
    };

var lineFunction = d3.svg.line()
        .x(function(d) { return d.x; })
        .y(function(d) { return d.y; })
        .interpolate  ("cardinal-closed")
        .tension(0)
        ;

var svg = d3.select("body").append("svg")
        .attr("width", w)
        .attr("height", h)
        ;


var path1 = svg.append("path")
        .datum( dataset1 )
        .attr("d", lineFunction)
        .attr("stroke", "black")
        .attr("stroke-width", 3)
        .attr("fill", "none")
        ;
var circle1 = svg.append("circle")
    .attr("r", 130)
    .attr("transform", "translate(" + [0] + ")")
    ;


var path2 = svg.append("path")
        .datum( dataset2 )
        .attr("d", lineFunction)
        .attr("stroke", "black")
        .attr("stroke-width", 3)
        .attr("fill", "none")
        ;

var circle2 = svg.append("circle")
    .attr("r", 30)
    .attr("transform", "translate(" + [0] + ")")
    ;

var path3 = svg.append("path")
        .datum( dataset2 )
        .attr("d", lineFunction)
        .attr("stroke", "black")
        .attr("stroke-width", 3)
        .attr("fill", "none")
        ;

var circle3 = svg.append("circle")
    .attr("r", 10)
    .attr("transform", "translate(" + [0] + ")")
    ;

transition();
function transition() {
  circle1.transition()
      .duration(10000)
      .attrTween("transform", translateAlong(path1.node()))
      .each("end", transition);
}


transition();
function transition() {
  circle2.transition()
      .duration(10000)
      .attrTween("transform", translateAlong(path2.node()))
      
}

transition();
function transition() {
  circle3.transition()
      .duration(10000)
      .attrTween("transform", translateAlong(path3.node()))
      
}

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

function translateAlong(path) {
  var l = path.getTotalLength();
  return function(d, i, a) {
    return function(t) {
      var p = path.getPointAtLength(t * l);
      return "translate(" + p.x + "," + p.y + ")";
    };
  };
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>

path {
  fill: none;
  stroke: red;
  stroke-width: 3px;
}

circle {
  fill: red;
  stroke: #fff;
  stroke-width: 3px;
  opacity: 0.7;

}

</style>

<script src="https://d3js.org/d3.v3.min.js"></script>

首先,您的代码可能有问题,因为您正在重新定义同一个函数。 transition() 函数有 3 个不同的定义(每个圆圈一个)。修复该代码后,我们就可以继续处理下一个问题。

您的代码有 3 个问题:

  1. 您正在将 dataset3 个值推入 dataset2 数组。
  2. 您正在使用 dataset2 数组绘制 path3 元素。
  3. 这是最重要的问题:您有 3 个同名函数。最后一个只是覆盖其他的。他们应该有不同的名字。或者,对于 DRY,编写一个通用函数并将圆和路径作为参数传递。

这是经过这些更改后的代码。

var w = 2000,
  h = 2000;

var dataset1 = [];
for (var i = 0; i < 5; i++) {
  var x = Math.floor((Math.random() * 900) + 1);
  var y = Math.floor((Math.random() * 900) + 1);
  dataset1.push({
    "x": x,
    "y": y
  });
};

var dataset2 = [];
for (var i = 0; i < 4; i++) {
  var x = Math.floor((Math.random() * 700) + 1);
  var y = Math.floor((Math.random() * 600) + 1);
  dataset2.push({
    "x": x,
    "y": y
  });
};

var dataset3 = [];
for (var i = 0; i < 3; i++) {
  var x = Math.floor((Math.random() * 800) + 1);
  var y = Math.floor((Math.random() * 400) + 1);
  dataset3.push({
    "x": x,
    "y": y
  });
};

var lineFunction = d3.svg.line()
  .x(function(d) {
    return d.x;
  })
  .y(function(d) {
    return d.y;
  })
  .interpolate("cardinal-closed")
  .tension(0);

var svg = d3.select("body").append("svg")
  .attr("width", w)
  .attr("height", h);


var path1 = svg.append("path")
  .datum(dataset1)
  .attr("d", lineFunction)
  .attr("stroke", "black")
  .attr("stroke-width", 3)
  .attr("fill", "none");
var circle1 = svg.append("circle")
  .attr("r", 130)
  .attr("transform", "translate(" + [0] + ")");


var path2 = svg.append("path")
  .datum(dataset2)
  .attr("d", lineFunction)
  .attr("stroke", "black")
  .attr("stroke-width", 3)
  .attr("fill", "none");

var circle2 = svg.append("circle")
  .attr("r", 30)
  .attr("transform", "translate(" + [0] + ")");

var path3 = svg.append("path")
  .datum(dataset3)
  .attr("d", lineFunction)
  .attr("stroke", "black")
  .attr("stroke-width", 3)
  .attr("fill", "none");

var circle3 = svg.append("circle")
  .attr("r", 10)
  .attr("fill", "blue")
  .attr("transform", "translate(" + [0] + ")");

transition();

function transition() {
  circle1.transition()
    .duration(10000)
    .attrTween("transform", translateAlong(path1.node()))
    .each("end", transition);
}


transition2();

function transition2() {
  circle2.transition()
    .duration(10000)
    .attrTween("transform", translateAlong(path2.node()))
    .each("end", transition2);

}

transition3();

function transition3() {
  circle3.transition()
    .duration(10000)
    .attrTween("transform", translateAlong(path3.node()))
    .each("end", transition3);

}

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

function translateAlong(path) {
  var l = path.getTotalLength();
  return function(d, i, a) {
    return function(t) {
      var p = path.getPointAtLength(t * l);
      return "translate(" + p.x + "," + p.y + ")";
    };
  };
}
path {
  fill: none;
  stroke: red;
  stroke-width: 3px;
}

circle {
  fill: red;
  stroke: #fff;
  stroke-width: 3px;
  opacity: 0.7;
}
<script src="https://d3js.org/d3.v3.min.js"></script>