javascript - d3 中的过渡碰撞检测

标签 javascript d3.js

根据这个例子http://bl.ocks.org/ahmohamed/c1804b03b71d8a17bd37

我想在碰撞发生时改变圆和静态点的颜色,所以我为它们添加了相同的类

var points =  svg.selectAll(".point")
    .data(points)
  .enter().append("circle").attr('class', 'dot')
    .attr("r", 20)
    .attr("transform", function(d) { return "translate(" + d + ")"; });

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

碰撞函数中我改成了这个

d3.selectAll('.dot').each(function(d,i){

代替

points.each(function(d,i){

但在那之后圆圈的颜色并没有变回正常,它一直是红色。

这是我的 JSFiddle: https://jsfiddle.net/psh2cphm/

求助!谢谢

最佳答案

一个更简单的替代方法是只保留对碰撞圆的引用:

if (!(x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1)) {
    collidingPoint = this;
    colliding = true;
}

然后:

if (collide(this)) {
    d3.select(this).style("fill", "red")
    d3.select(collidingPoint).style("fill", "red")
} else {
    d3.select(this).style("fill", "steelblue")
    d3.select(collidingPoint).style("fill", "steelblue")
}

下面是修改后的代码:

<!DOCTYPE html>
<meta charset="utf-8">

<body>
  <style>
    path {
      fill: none;
      stroke: #000;
      stroke-width: 3px;
    }
    
    circle {
      fill: steelblue;
      stroke: #fff;
      stroke-width: 3px;
    }

  </style>
  <script src="https://d3js.org/d3.v3.min.js"></script>
  <script>
    var points = [
      [480, 200],
      [580, 400],
      [680, 100],
      [780, 300],
      [180, 300],
      [280, 100],
      [380, 400]
    ];

    var collidingPoint;

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

    var path = svg.append("path")
      .data([points])
      .attr("d", d3.svg.line()
        .tension(0) // Catmull–Rom
        .interpolate("cardinal-closed"));

    var points = svg.selectAll(".point")
      .data(points)
      .enter().append("circle").attr('class', 'dot')
      .attr("r", 20)
      .attr("transform", function(d) {
        return "translate(" + d + ")";
      });

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

    transition();

    function transition() {
      circle.transition()
        .duration(30000)
        .tween("attr", translateAlong(path.node()))
        .each("end", transition);
    }

    // Returns an attrTween for translating along the specified path element.
    function translateAlong(path) {
      var l = path.getTotalLength();
      return function(d, i, a) {
        return function(t) {
          var p = path.getPointAtLength(t * l);

          d3.select(this).attr("transform", "translate(" + p.x + "," + p.y + ")");
          if (collide(this)) {
            d3.select(this).style("fill", "red")
            d3.select(collidingPoint).style("fill", "red")
          } else {
            d3.select(this).style("fill", "steelblue")
            d3.select(collidingPoint).style("fill", "steelblue")
          }
        };
      };
    }

    points.each(function(d, i) {
      var ntrans = d3.transform(d3.select(this).attr("transform")).translate,
        nx1 = ntrans[0],
        nx2 = ntrans[0] + (+d3.select(this).attr("r")),
        ny1 = ntrans[1],
        ny2 = ntrans[1] + (+d3.select(this).attr("r"));
    });

    function collide(node) {
      var trans = d3.transform(d3.select(node).attr("transform")).translate,
        x1 = trans[0],
        x2 = trans[0] + (+d3.select(node).attr("r")),
        y1 = trans[1],
        y2 = trans[1] + (+d3.select(node).attr("r"));

      var colliding = false;
      points.each(function(d, i) {
        var ntrans = d3.transform(d3.select(this).attr("transform")).translate,
          nx1 = ntrans[0],
          nx2 = ntrans[0] + (+d3.select(this).attr("r")),
          ny1 = ntrans[1],
          ny2 = ntrans[1] + (+d3.select(this).attr("r"));


        if (!(x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1)) {
          collidingPoint = this;
          colliding = true;
        }
      })

      return colliding;
    }

  </script>

关于javascript - d3 中的过渡碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48218572/

相关文章:

javascript - AngularJS 和 D3 - JavaScript RangeError : Maximum call stack size exceeded in recursion

javascript - 执行 RemoveFormat 时删除 <br> 标签

javascript - 如何添加 "doesn' t 触发“for..in”的新数组方法?

javascript - 处理 JQuery ajax 成功对象数据

javascript - Addy Osmanis pub/sub,难以理解代码

javascript - 让点鼠标交互和画笔协同工作

javascript - 通过单击按钮更改加载到表中的 JSON 文件

javascript - 如何确定回调函数的参数列表

javascript - 使用 JavaScript 在服务器上保存 json 文件

javascript - D3 树形图更新 - 并非所有元素都被删除