Границы масштабирования

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

В Snap.svg масштабирование осуществляется с помощью метода transform(). Этот метод принимает строку трансформации, которая может содержать несколько операций: translate, rotate, scale, skewX, skewY. Масштабирование обозначается с помощью scale(sx, sy), где sx и sy — коэффициенты изменения по горизонтали и вертикали.

var s = Snap(800, 600);
var circle = s.circle(100, 100, 50);
circle.transform('scale(2, 2)');

В приведённом примере круг увеличивается в 2 раза по обеим осям. Если второй параметр опущен (scale(2)), масштаб применяется одинаково к оси X и Y.

Установка границ масштабирования

Для ограничения масштабирования элементов используется комбинация методов getBBox() и проверок текущего масштаба. Метод getBBox() возвращает объект с размерами и координатами элемента:

var bbox = circle.getBBox();
console.log(bbox); // {x, y, width, height, cx, cy}

Используя значения bbox.width и bbox.height, можно определить текущие размеры и вычислять новые размеры с учётом максимальных и минимальных границ:

var minScale = 0.5;
var maxScale = 3;
var currentScale = 1;

function scaleElement(el, factor) {
    var newScale = currentScale * factor;
    if(newScale < minScale) newScale = minScale;
    if(newScale > maxScale) newScale = maxScale;
    el.transform('scale(' + newScale + ')');
    currentScale = newScale;
}

Здесь переменные minScale и maxScale задают ограничения для масштабирования, предотвращая чрезмерное уменьшение или увеличение элемента.

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

По умолчанию трансформация scale применяется относительно начала координат SVG (0,0). Чтобы масштабировать элемент относительно его центра, используется синтаксис scale(sx, sy, cx, cy), где cx и cy — координаты центра:

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

Для динамического получения центра элемента удобно использовать getBBox().cx и getBBox().cy:

var bbox = circle.getBBox();
circle.transform(`scale(1.5, 1.5, ${bbox.cx}, ${bbox.cy})`);

Комбинированные трансформации

Масштабирование часто применяется вместе с перемещением (translate) и вращением (rotate). В Snap.svg порядок операций важен, так как трансформации выполняются последовательно. Например:

circle.transform(`translate(50, 50) scale(2, 2, ${bbox.cx}, ${bbox.cy}) rotate(45, ${bbox.cx}, ${bbox.cy})`);

В этом примере сначала элемент перемещается, затем масштабируется относительно своего центра, и после этого вращается вокруг того же центра.

Масштабирование всего SVG

Иногда необходимо масштабировать всю сцену SVG. Для этого можно создать группу элементов с помощью g() и применять масштаб к группе:

var group = s.group(circle, rect, path);
group.transform('scale(1.5)');

Преимущество группировки в том, что все дочерние элементы масштабируются синхронно, сохраняя пропорции и расположение относительно друг друга.

Анимация масштабирования

Snap.svg поддерживает плавное изменение масштаба через метод animate(). Можно анимировать масштаб с ограничениями, создавая эффект увеличения или уменьшения с контролем границ:

var targetScale = 2;
var minScale = 0.5;
var maxScale = 3;

circle.animate({ transform: `scale(${Math.min(maxScale, Math.max(minScale, targetScale))}, ${Math.min(maxScale, Math.max(minScale, targetScale))}, ${bbox.cx}, ${bbox.cy})` }, 1000, mina.easeinout);

Метод mina.easeinout обеспечивает плавное ускорение и замедление анимации, делая визуальный эффект более естественным.

Практическая организация границ масштабирования

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

function setScale(el, scaleFactor) {
    var bbox = el.getBBox();
    var newScale = Math.min(maxScale, Math.max(minScale, scaleFactor));
    el.transform(`scale(${newScale}, ${newScale}, ${bbox.cx}, ${bbox.cy})`);
}

Такая функция позволяет централизованно контролировать все элементы и предотвращает случайное превышение допустимых границ.

Итоговые рекомендации

  • Всегда использовать центр элемента для корректного масштабирования.
  • Ограничивать масштаб с помощью минимальных и максимальных значений.
  • При работе с группами элементов масштабировать именно группу, чтобы сохранить пропорции.
  • Для анимаций использовать метод animate() с easing-функциями.
  • Проверять текущие размеры через getBBox() перед применением новых трансформаций.

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