Масштабирование элементов

В Snap.svg масштабирование графических элементов является одной из ключевых операций при работе с векторной графикой. Масштабирование позволяет изменять размеры объектов, сохраняя их пропорции или трансформируя только по отдельным осям.

Основной метод масштабирования: transform

Каждый элемент Snap.svg поддерживает метод transform, который принимает строку с командами трансформаций. Для масштабирования используется команда s:

var s = Snap(400, 400);
var circle = s.circle(100, 100, 50);
circle.transform("s2"); // Масштабирует по обеим осям в 2 раза

Строка "s2" означает масштабирование по оси X и Y в два раза относительно начала координат (0,0). Если требуется масштабировать относительно конкретной точки (cx, cy), используется формат:

circle.transform("s2,2,100,100"); // Масштабирование x2 по X и Y относительно точки (100,100)

Здесь:

  • первый параметр — коэффициент по X
  • второй — коэффициент по Y
  • третий и четвертый — координаты центра масштабирования

Масштабирование с сохранением текущих трансформаций

Метод transform заменяет все предыдущие трансформации. Чтобы добавить масштабирование к существующим трансформациям, используется символ ...:

circle.transform(circle.transform().localMatrix + "s1.5,1.5,100,100");

Однако удобнее применять цепочку методов через element.scale():

circle.scale(1.5, 1.5, 100, 100);

Параметры scale(sx, sy, cx, cy):

  • sx — масштаб по X
  • sy — масштаб по Y (если не указан, равен sx)
  • cx, cy — координаты центра масштабирования

Если центр не указан, масштабирование происходит относительно точки (0,0).

Масштабирование относительно центра объекта

Для масштабирования относительно геометрического центра элемента, можно получить координаты центра с помощью метода getBBox():

var bbox = circle.getBBox();
circle.scale(2, 2, bbox.cx, bbox.cy);

Метод getBBox() возвращает объект с параметрами:

  • x, y — координаты верхнего левого угла
  • width, height — размеры элемента
  • cx, cy — центр элемента

Это позволяет точно контролировать точку, относительно которой выполняется трансформация.

Масштабирование с анимацией

Snap.svg поддерживает анимацию любых трансформаций, включая масштабирование, через метод animate:

circle.animate({ transform: "s2,2,100,100" }, 1000, mina.easeinout);

Аргументы метода:

  • первый — объект атрибутов и трансформаций
  • второй — длительность анимации в миллисекундах
  • третий — функция интерполяции (mina.linear, mina.easein, mina.easeout, mina.easeinout)

Для последовательного масштабирования относительно центра объекта:

var bbox = circle.getBBox();
circle.animate({ transform: `s1.5,1.5,${bbox.cx},${bbox.cy}` }, 1000, mina.easeinout);

Масштабирование группы элементов

Если элементы объединены в группу через group или g, масштабирование можно применить ко всей группе:

var g = s.group(circle, s.rect(50, 50, 100, 100));
g.scale(1.5, 1.5, 100, 100);

Все элементы группы масштабируются одновременно, сохраняя свои относительные позиции.

Комбинация масштабирования с другими трансформациями

Snap.svg позволяет комбинировать несколько трансформаций: перемещение (t), поворот (r), масштабирование (s). Пример:

circle.transform("t50,50 r45 s2,2,100,100");

Последовательность команд важна: трансформации выполняются слева направо. Масштабирование после перемещения и поворота изменяет окончательный результат.

Масштабирование с сохранением пропорций

Если требуется масштабировать элемент равномерно по обеим осям, достаточно указать один коэффициент:

circle.scale(1.5); // sx = sy = 1.5

Для несоразмерного масштабирования используются два коэффициента:

circle.scale(2, 1); // X увеличен в 2 раза, Y — не изменен

Это полезно при создании искажений или эффекта растягивания.

Масштабирование и взаимодействие с координатами мыши

Для интерактивных приложений часто необходимо масштабирование относительно точки курсора. Используется событие mousemove и передача координат в метод scale:

s.mousemove(function(event) {
    var cx = event.offsetX;
    var cy = event.offsetY;
    circle.transform(`s1.05,1.05,${cx},${cy}`);
});

Такой подход позволяет реализовать динамическое масштабирование объектов в зависимости от положения мыши.

Практические рекомендации

  • Всегда учитывать центр масштабирования, чтобы объект не “уезжал” из видимой области.
  • Для анимаций лучше использовать animate с трансформациями, а не постоянное изменение атрибутов r или width/height, чтобы сохранить плавность.
  • При работе с группами сначала определять общий bbox, чтобы масштабирование было корректным относительно всей композиции.
  • Комбинированные трансформации лучше записывать в одну строку, чтобы избежать неожиданных эффектов при повторных вызовах transform.

Масштабирование в Snap.svg — мощный инструмент для управления размером и пропорциями объектов, позволяющий создавать как статические, так и динамические графические элементы с высокой точностью.