Как повернуть или масштабировать (преобразовать) путь SVG относительно его центральной точки?

Я пытаюсь вращать и масштабировать фигуры в SVG вокруг их центральной точки. Я изучил несколько библиотек, в том числе Jquery, Greensock, D3, RaphaelJS, но не смог найти ни одной, которая обеспечивала бы простой способ сделать это. Каждый анимирует форму из исходной точки (как я понимаю, по умолчанию). Я хочу иметь возможность вращать фигуру вокруг ее центральной точки или масштабировать ее вверх или вниз от центральной точки.

Вот пара примеров использования Greensock и D3, иллюстрирующих поведение по умолчанию: http://jsbin.com/AHEXiPa/1/edit?html,js,output

Каждый из этих примеров отскакивает и выходит из верхнего левого угла, а не остается неподвижным и расширяется от центра треугольника во всех направлениях.

Может ли одна из библиотек, которые я упомянул, выполнить это, или есть другая библиотека или метод, который я должен рассмотреть?

В идеале мне нужно иметь возможность применить анимацию/преобразование к существующему объекту в DOM. Например, D3 хорош в этом, но Raphael, кажется, требует сначала преобразовать SVG в Raphael, прежде чем вводить его в DOM.


person Matt    schedule 28.01.2014    source источник
comment
Вы пробовали искать ТАК по фразе svg rotate вокруг центра? Вы получаете много ответов, включая решения для Raphael, D3 и простого JavaScript.   -  person Paul LeBeau    schedule 28.01.2014


Ответы (3)


На самом деле это случай выбора библиотеки, которая соответствует вашим потребностям, и тогда вы найдете способ. Как говорит BigBadaboom, если вы выполните поиск, вы найдете множество решений.

Чтобы попытаться объединить ваши вопросы, поскольку иногда сложнее всего использовать существующий объект DOM, я включил пример в Snap.svg. Вы часто можете сделать что-то подобное в большинстве библиотек.

jsfiddle здесь Fiddle, используя существующий HTML-код.

s = Snap("#mySVGContainer1");   // create a canvas from existing svg

var triangle1 = s.select("#myShape1").transform("r90"); //select&transform existing object


p = Snap("#mySVGContainer2");

var triangle2 = p.select("#myShape2");
var bbox = triangle2.getBBox(); //bounding box, centre cx/cy

//rotate and scale with transform string (raphael/snap format)
triangle2.animate({ transform: "r180," + bbox.cx + ',' + bbox.cy + "s3,3," + bbox.cx + "," + bbox.cy }, 2000);  
person Ian    schedule 28.01.2014
comment
Это пока мой любимый вариант. Я действительно ищу что-то с как можно меньшим беспокойством, поэтому объединение элементов в дополнительные группы (что, кажется, является преобладающим вариантом в других потоках) менее желательно. Отлично сделано, и спасибо за помощь! - person Matt; 30.01.2014

Для вращений, как указывает @Ian, вы можете указать центр вращения. Для других преобразований изменения определяются относительно точки пути (0,0).

Самый простой способ заставить преобразования работать относительно центра пути:

  1. Определите путь так, чтобы он был сосредоточен вокруг точки (0,0); или
  2. Оберните путь в элемент <g>, а затем переместите его так, чтобы он центрировался в точке (0,0) системы координат элемента <g>.

Затем вы можете применять повороты, масштабирование и преобразования (к элементу <g>, если используете), и все они будут хорошо центрированы.

Самое сложное — найти «центр» произвольной формы. @ Подход Яна к использованию центра ограничивающей рамки обычно дает достойные результаты. Если ваша фигура представляет собой многоугольник, вы можете использовать функции d3. .

Пример, показывающий фигуру, перемещающуюся с помощью мыши, вращающуюся и изменяющую масштаб, центр которой находится вокруг центра ограничивающей рамки:
http://fiddle.jshell.net/LgfE3/

Изменить: упрощенный jsfiddle

person AmeliaBR    schedule 30.01.2014
comment
Очень нравится ваш пример, особенно с использованием другой библиотеки. - person Ian; 10.02.2014

Давно искал, остановился на следующем.

1. Создайте фигуру svg в координатах x:0,y:0.

2. Определите вручную центр вращения, например, center = [ x:50,y:100].

3. Создайте spinIt() функцию, например:

function spinIt() {
    needle.transition()
        .duration(2000)
        .attrTween("transform", tween);
    function tween() {
        return d3.interpolateString("rotate(-180, 50, 100)", "rotate(90, 50, 100)");
    }
}

4. Используйте его в триггере:

svg.on("click", spinIt);

http://jsfiddle.net/SHF2M/79/

person Hugolpz    schedule 23.11.2014