Чтобы повернуть 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() есть простое решение. a> метод (код на CoffeeScript; см. ниже версию JavaScript*):
centerToOrigin = (el) ->
boundingBox = el.getBBox()
return {
x: -1 * Math.floor(boundingBox.width/2),
y: -1 * Math.floor(boundingBox.height/2)
}
Теперь вы можете центрировать свой элемент/группу, передав элемент без обертки (используя метод .node()
D3)
group = d3.select("g.rotate-me")
center = centerToOrigin(group.node())
group.attr("transform", "translate(#{center.x}, #{center.y})")
Код, который реализует это как на одном <rect>
, так и на <g>
из 2 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 + ")");
person
rdickert
schedule
14.02.2013