translate
SVG オブジェクトを任意の軸で回転するには、(軸を設定する) と の2 つの変換が必要です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
<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>
a singleと <g>
of of 2rect
の両方で再配置とスケーリングを使用してこれを実装するコードについては、この 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 + ")");