2013-02-14 78 views
7

我在d3.js中有两个简单对象,它们应该围绕视口中心(如太阳周围的行星)旋转。如何在d3.js中围绕中心旋转对象

我是d3.js的新手,我知道我必须使用转换,但是因为行星必须始终循环,而不仅仅是进入或退出,我不知道在哪里以及如何设置转场。

这里是我当前的代码:

var planets = [ 
    {d:100,r:2}, 
    {d:150,r:4} 
]; 

var w = 500, h = 400, svg, circle; 

function init(){ 

    svg = d3.select("#drawArea").append("svg").attr({width: w, height: h}); 

    var center = { 
     x: Math.floor(w/2), 
     y: Math.floor(h/2) 
    }; 

    svg.append('circle').attr({ 
     'cx': center.x, 
     'cy': center.y, 
     'r': 10, 
     'class': 'sun' 
    }); 

    circle = svg.selectAll(".planet") 
     .data(planets) 
     .enter() 
      .append("circle") 
       .attr("class", "planet") 
       .attr("r", function(s){return s.r}); 

    circle.attr({ 
     // distance from the center 
     'cx': function(s){ return center.x - s.d; }, 
     // center of the screen 
     'cy': function(s){ return center.y; } 
    }); 

} 

这里是一个jsfiddle打转转。

回答

13

您需要:

  1. 将您在g组行星的g是在你的太阳
  2. 中心的创建,你旋转你的团的d3.timer

对于使用d3.timer的示例,请参阅Mike Bostocks Epicyclic Gearing示例。使用这个例子,我放在一起类似的东西给你问:举例http://bl.ocks.org/4953593

核心:

var w = 800, h = 800; 
    var t0 = Date.now(); 

    var planets = [ 
    { R: 300, r: 5, speed: 5, phi0: 90}, 
    { R: 150, r: 10, speed: 2, phi0: 190} 
    ]; 


    var svg = d3.select("#planetarium").insert("svg") 
    .attr("width", w).attr("height", h); 

    svg.append("circle").attr("r", 20).attr("cx", w/2) 
    .attr("cy", h/2).attr("class", "sun") 

    var container = svg.append("g") 
    .attr("transform", "translate(" + w/2 + "," + h/2 + ")") 

    container.selectAll("g.planet").data(planets).enter().append("g") 
    .attr("class", "planet").each(function(d, i) { 
     d3.select(this).append("circle").attr("class", "orbit") 
     .attr("r", d.R); 
     d3.select(this).append("circle").attr("r", d.r).attr("cx",d.R) 
     .attr("cy", 0).attr("class", "planet"); 
    }); 

    d3.timer(function() { 
    var delta = (Date.now() - t0); 
    svg.selectAll(".planet").attr("transform", function(d) { 
     return "rotate(" + d.phi0 + delta * d.speed/200 + ")"; 
    }); 
    }); 
+0

真棒,非常感谢你,并欢迎计算器! – Marc 2013-02-15 00:04:52

+0

我知道这是旧的,但我碰到这个职位。为什么和这个星球在旋转?我做了一些只旋转星球的测试,只有组和结果是一样的,除了慢一点(这是正常的,因为我削减了一半的旋转效果)。 – vIceBerg 2016-12-03 15:35:59

2

我知道这可能来得太晚了。但我希望这能够帮助未来的读者,如果他们也面临同样的问题。 我创建了小提琴,并在这里添加一些解释,希望它可以帮助:

http://www.zestyrock.com/data-visualization/d3-rotate-object-around-the-center-object-part-2/

下面是代码:

var start = Date.now(); 

var mode = 0; 

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

svg.append("circle") 
    .attr("r", 50) 
    .attr("cx", 250) 
    .attr("cy", 250) 
    .attr("fill", "#e05038"); 

var rotateElements = svg.append("g"); 

rotateElements.append("circle") 
    .attr("r", 25) 
    .attr("cx", 250) 
    .attr("cy", 50) 
    .attr("fill", "#f2b632") 
    .attr("class", "orangeNode"); 

rotateElements.append("line") 
    .attr("x1", 250) 
    .attr("y1", 75) 
    .attr("x2", 250) 
    .attr("y2", 200) 
    .attr("class", "edge") 
    .attr("stroke", "grey"); 


d3.select("#start") 
    .on("click", startAnimation); 

function startAnimation() { 
    if (mode === 0) { 
     d3.timer(function() { 
      var angle = (Date.now() - start); 
      var transform = function() { 
       return "rotate(" + angle + ", 250, 250)"; 
      }; 
      d3.selectAll(".orangeNode, .edge") 
       .attr("transform", transform); 

      if (mode === 0) { 
       return true; 
      } else { 
       return false; 
      } 
     }); 
     mode = 1; 
    } else { 
     mode = 0; 
    } 

} 
+1

链接已过时 – luQ 2017-08-07 14:20:02