与旋转相结合的过渡有奇怪的结果。
以下是我的问题:http://jsfiddle.net/emperorz/E3G3z/1/ 尝试点击每个方块以查看不同的行为。
请原谅被黑客入侵的代码,但如果我使用带有旋转的转换(以及x / y放置),那么它就会循环播放。
我试过了:
1)所有在变换中(旋转然后翻译),这看起来大多没问题。有点不稳定。
2)只需在变换中旋转,使用x / y属性定位。飞到各处,但最终到达正确的位置。非常奇怪。
3)变换中的所有内容(平移然后旋转),飞走,并最终进入(完全)错误的位置。
嗯。奇怪。
是否有正确的方法来旋转带有过渡的形状?
直观地说,如果第二种选择有效,那就太好了。
由于
答案 0 :(得分:6)
要在任意轴上旋转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>
将translate (-100, -50)
置于(0,0)上。如果将旋转应用于<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})")
对于使用重新定位和缩放see this fiddle的<rect>
的{{1}}和<g>
来实现此目的的代码,{{3}}。
*以上代码的Javascript:
rect
答案 1 :(得分:0)
iirc translate相对于0,0而旋转是围绕对象的中心点
因此,因为您的形状偏离0,0(例如100,200或200,100),所以它们在翻译时最终会迁移。这可以通过将Diamond3的偏移更改为[50,50]来看到 - 围绕屏幕的迁移小得多
解决方案是将0,0点重新定位到钻石的中心。在D3中有一种方法可以做到这一点 - 但是我无法记住它在我的头脑中是什么:(