如何围绕焦点旋转d3.js节点?

时间:2016-02-26 19:54:53

标签: javascript d3.js

我一直在使用力量布局作为我制作的棋盘游戏的物理引擎,并且它一直运作良好。但是,我一直试图弄清楚是否有可能围绕特定焦点旋转节点。考虑一下codepen。我想让codepen中的3个绿色节点以统一的方式围绕焦点旋转。在tick()函数中,我执行以下操作:

var k = .1 * e.alpha;

// Push nodes toward their designated focus.
nodes.forEach(function(o, i) {
  o.y += (foci[o.id].y - o.y) * k;
  o.x += (foci[o.id].x - o.x) * k;
});

与将节点推向焦点的方式相同,我想将指定为焦点的所有节点围绕所述焦点旋转。有没有办法通过操作tick()函数中的o.yo.x变量来实现这一目的?我曾尝试使用this formula手动设置x和y值,但我认为力布局的电荷和重力可能会使它变得混乱。有什么想法吗?

我知道我使用强制布局来做它不太想做的事情,但任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:2)

我已经搞乱了你的代码,以获得一个点的基本动作。

我将foci var更改为只有两点的对象:

 foci = {
    x: 300,
    y: 100
  };

我添加了数据,你必须给每个节点一个起点:

nodes.push({
  id: 0,
  x:20,
  y:30
});
nodes.push({
  id: 0,
  x:40,
  y:60
});
nodes.push({
  id: 0,
  x:80,
  y:10
});

我为每个节点添加了一个角度,以便您以后可以单独使用它们:

 .attr("cx", function(d) {
            d.angle = 0; //added
      return d.x;
    })

并更改了勾号,以便每个节点围绕焦点移动。如前所述,我添加了一个角度,因为这些点将围绕具有不同尺寸半径的不同圆圈移动,因为它们距离焦点点的距离不同。如果你使用一个角度,那么所有节点都将在彼此的顶部移动,这是毫无意义的:

圆上点的公式:

//c = centre point, r = radius, a = angle
x = cx + r * cos(a)
y = cy + r * sin(a)

在勾选中使用:

var radius = 100; //made up radius

  node
    .attr("cx", function(d) {
       if(d.angle>(2*Math.PI)){ restart at full circle
         d.angle=0;
       }
    d.x = foci.x + radius *Math.cos(d.angle) //move x

      return d.x;
    })
    .attr("cy", function(d) {
    d.y = foci.y + radius *Math.sin(d.angle) //move y
      return d.y;
    });

更新了小提琴:https://jsfiddle.net/reko91/yg0rs4xc/7/

这应该很容易实现从圆圈运动变为椭圆运动:))

再看一遍,这只会在一半左右。这是由于滴答功能仅持续几秒钟。如果单击其中一个节点,它将围绕圆圈继续。如果你想要连续发生这种情况,你必须设置一个计时器功能,这样它就会绕着圆圈不停地运行,但这应该很容易实现。

而不是使用滴答功能只需在内部使用定时器创建另一个函数,在加载时调用它并且它将连续运行:)

相关问题