要在任意轴上旋转 SVG 对象,您需要两个转换:(translate
设置轴)和rotate
. 你真正想要的是先translate
完全应用然后旋转已经移动的元素,但它看起来是独立和同时操作的translate
。rotate
这在正确的位置结束,但动画translate
基本上是在旋转过程中移动轴,从而产生摆动。您可以通过让它们出现在 SVG 元素层次结构中的不同位置translate
来隔离它们。rotate
例如,看看以下内容:
<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
。就是这样。您现在可以完全控制您的变换。
找到 a<rect>
的中心很容易,但要找到 a <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 s 上实现此功能的代码,请参阅此 fiddle。rect
*以上代码的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 + ")");