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

时间:2017-09-06 16:17:49

标签: d3.js svg jquery-animate

我试图沿3条路径设置3个圆圈的动画,这些路径是随机生成的。只生成两条路径,只有一条圆形沿其分配的路径动画。我试过配对数据集和圈子,这没有效果。

其中一条路径似乎是混合两个数据集来生成怪物路径。我怎么阻止这个?如何将每个圆圈分配到其分配的路径?

这可能是一种更优雅的方式。

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>

2 个答案:

答案 0 :(得分:1)

您的代码遇到3个问题:

  1. 您正在将dataset3值推送到dataset2数组。
  2. 您使用dataset2数组绘制path3元素。
  3. 这是最重要的问题:您有3个具有相同名称的功能。最后一个简单地覆盖其他的。他们应该有不同的名字。或者,对于DRY,编写一个通用函数并将圆和路径作为参数传递。
  4. 以下是包含这些更改的代码。

    &#13;
    &#13;
    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 + ")";
        };
      };
    }
    &#13;
    path {
      fill: none;
      stroke: red;
      stroke-width: 3px;
    }
    
    circle {
      fill: red;
      stroke: #fff;
      stroke-width: 3px;
      opacity: 0.7;
    }
    &#13;
    <script src="https://d3js.org/d3.v3.min.js"></script>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:0)

首先,您可能遇到代码问题,因为您正在重新定义相同的功能。 transition()函数有3种不同的定义(每个圆圈一个)。一旦修复了该代码,我们就可以继续讨论下一个问题。