javascript 如何在 d3.js 中围绕中心旋转对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14872687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to rotate an object around the center in d3.js
提问by Marc
I have two simple objects in d3.js, they should be circling around the center of the viewport (like planets around the sun).
我在 d3.js 中有两个简单的对象,它们应该围绕视口的中心盘旋(就像围绕太阳的行星)。
I am new to d3.js and I know that I have to use transitions but as the planets have to circle all the time and not just on enter or exit I don't know where and how to set the transition.
我是 d3.js 的新手,我知道我必须使用过渡,但由于行星必须一直在旋转,而不仅仅是在进入或退出时,我不知道在哪里以及如何设置过渡。
Here is my current code:
这是我当前的代码:
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; }
});
}
And here is a jsfiddleto play around.
这是一个可以玩的jsfiddle。
回答by Jan van der Laan
You need to:
你需要:
- Place your planets in
g
groups in ag
that is centered on your sun - Create an
d3.timer
in which you rotate your group.
- 将您的行星
g
分组放置在g
以您的太阳为中心的一组中 - 创建一个
d3.timer
在其中轮换您的小组。
For, example of the use of d3.timer
see Mike Bostocks Epicyclic Gearingexample. Using that example, I put together something similar to what you asked: http://bl.ocks.org/4953593
例如,使用示例d3.timer
参见 Mike Bostocks Epicyclic Gearing示例。使用那个例子,我把类似于你问的东西放在一起:http: //bl.ocks.org/4953593
Core of the example:
例子的核心:
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 + ")";
});
});
回答by catlovespurple
I know this might come too late. But I do hope this can help future readers if they also are facing the same problem. I created fiddles and add some explanation in here, hope it can help:
我知道这可能来得太晚了。但我确实希望这可以帮助未来的读者,如果他们也面临同样的问题。我创建了小提琴并在这里添加了一些解释,希望它可以帮助:
http://www.zestyrock.com/data-visualization/d3-rotate-object-around-the-center-object-part-2/
http://www.zestyrock.com/data-visualization/d3-rotate-object-around-the-center-object-part-2/
Here is the code:
这是代码:
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;
}
}