过渡与旋转相结合会产生奇怪的结果。
这是我的问题的 fiddle :http://jsfiddle.net/emperorz/E3G3z/1/ 尝试点击每个方 block 以查看不同的行为。
请原谅被黑的代码,但如果我使用带旋转(和 x/y 放置)的过渡,它就会循环。
我试过:
1) 全部在变换中(旋转然后平移),这似乎基本没问题。有点摇晃。
2) 只需在变换中旋转,使用 x/y 属性定位。飞得到处都是,但最终飞到了正确的位置。很奇怪。
3) 全部在变换(平移然后旋转)中,飞走,并最终到达(完全)错误的位置。
嗯。奇怪。
是否有使用过渡旋转形状的正确方法?
直觉上,如果第二个选项可行就好了。
谢谢
最佳答案
要在任意轴上旋转 SVG 对象,您需要两个转换:translate
(设置轴)和 rotate
.你真正想要的是应用 translate
首先完全旋转然后旋转已经移动的元素,但看起来 translate
和 rotate
独立并同时运作。这在正确的地方结束,但是动画 translate
本质上是在旋转过程中移动轴,从而产生摆动。您可以隔离 translate
来自 rotate
通过让它们出现在 SVG 元素层次结构中的不同位置。例如,请看以下内容:
<g class="outer">
<g class="rect-container">
<rect class="rotate-me" width=200 height=100 />
</g>
</g>
您可以将 <rect>
居中在 (0,0) 上与 translate (-100, -50)
.如果您将旋转应用于 <rect>
,它会摆动元素,但如果你 rotate
它会干净地旋转g.rect-container
元素。如果您想重新定位、缩放或以其他方式进一步转换元素,请在 g.outer
上执行此操作.就是这样。您现在可以完全控制您的转换。
寻找 <rect>
的中心很容易,但要找到 <path>
的中心, <g>
等就难多了。幸运的是,.getBBox() 中提供了一个简单的解决方案。方法(CoffeeScript 中的代码;请参阅下面的 JavaScript 版本*):
centerToOrigin = (el) ->
boundingBox = el.getBBox()
return {
x: -1 * Math.floor(boundingBox.width/2),
y: -1 * Math.floor(boundingBox.height/2)
}
您现在可以通过传递非包装元素(使用 D3 的 .node()
方法)将您的元素/组居中
group = d3.select("g.rotate-me")
center = centerToOrigin(group.node())
group.attr("transform", "translate(#{center.x}, #{center.y})")
对于在单个 <rect>
上实现此功能的代码和 <g>
共 2 个 rect
s 重新定位和缩放,see this fiddle .
*以上代码的Javascript:
var center, centerToOrigin, group;
centerToOrigin = function(el) {
var boundingBox;
boundingBox = el.getBBox();
return {
x: -1 * Math.floor(boundingBox.width / 2),
y: -1 * Math.floor(boundingBox.height / 2)
};
};
group = d3.select("g.rotate-me");
center = centerToOrigin(group.node());
group.attr("transform", "translate(" + center.x + ", " + center.y + ")");
关于javascript - d3的transition和rotation能不能配合好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12494447/