【问题标题】:How to rotate an object around the center in d3.js如何在 d3.js 中围绕中心旋转对象
【发布时间】:2013-02-14 10:27:54
【问题描述】:

我在 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 可以玩。

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    你需要:

    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 + ")";
        });
      });
    

    【讨论】:

    • 我知道它很旧,但我遇到了这篇文章。 和行星旋转有什么原因吗?我做了一些只旋转行星和只旋转组的测试,结果是一样的,只是慢了一点(这是正常的,因为我将旋转效果削减了一半)。
    【解决方案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;
        }
    
    }
    

    【讨论】:

    • 链接已过期
    • 非常有帮助,看起来比我发现的任何其他东西都更容易理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多