Сохранение пропорций

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


Метод viewbox

viewbox задает область координат для контейнера SVG и позволяет масштабировать все вложенные элементы пропорционально. Синтаксис:

const draw = SVG().addTo('body').size(500, 300);
draw.viewbox(0, 0, 500, 300);

Пояснение ключевых моментов:

  • Параметры viewbox(x, y, width, height) задают виртуальную координатную сетку.
  • Все объекты внутри SVG масштабируются так, чтобы вписаться в размеры контейнера, сохраняя пропорции.
  • Комбинация size() и viewbox() позволяет адаптировать графику к разным размерам экрана.

Масштабирование с scale()

Метод scale() используется для изменения размеров элементов. Существует несколько вариантов:

const rect = draw.rect(100, 50).fill('blue');
rect.scale(2); // Увеличение в 2 раза по обеим осям
rect.scale(1.5, 2); // Разное масштабирование по x и y

Особенности:

  • Если указать один параметр, масштаб применяется одинаково по обеим осям, что сохраняет пропорции.
  • Для сохранения пропорций при разных осях рекомендуется вычислять соотношение ширины и высоты исходного элемента.

Пропорциональное изменение с size()

Метод size(width, height) изменяет размеры объекта, а для сохранения пропорций часто используют вычисление соотношения:

const circle = draw.circle(100).fill('red');
const ratio = circle.width() / circle.height();
circle.size(150, 150 / ratio);

Принцип работы:

  • Сначала определяется текущее соотношение сторон объекта.
  • Далее одно измерение задается явно, а второе вычисляется через соотношение, что предотвращает искажение формы.

Использование атрибута preserveAspectRatio

SVG поддерживает атрибут preserveAspectRatio, который управляет тем, как элемент вписывается в контейнер:

draw.image('example.png').size(300, 200).attr({
  preserveAspectRatio: 'xMidYMid meet'
});

Расшифровка значений:

  • xMidYMid — выравнивание по центру.
  • meet — масштабирование, при котором весь объект помещается в контейнер без обрезки.
  • slice — объект заполняет весь контейнер, возможна обрезка частей.

Трансформации с сохранением пропорций

При комбинировании трансформаций (поворот, масштаб, смещение) важно соблюдать порядок операций:

rect.scale(2).translate(50, 50).rotate(45);
  • Сначала применяется масштаб, затем смещение и поворот.
  • Масштабирование с одним коэффициентом гарантирует сохранение пропорций.
  • Для сложных графических сцен можно использовать группировку:
const group = draw.group();
group.add(rect).add(circle);
group.scale(1.5);
  • Все элементы внутри группы масштабируются пропорционально, что удобно для анимаций и адаптивной графики.

Автоматическое подгонка под контейнер

SVG.js предоставляет методы bbox() и transform() для вычисления размеров и корректного масштабирования:

const box = rect.bbox();
const scale = Math.min(500 / box.width, 300 / box.height);
rect.transform({ scale });
  • bbox() возвращает реальные размеры объекта с учетом всех трансформаций.
  • Вычисление минимального коэффициента гарантирует, что объект впишется в контейнер без искажений.

Применение в анимациях

Для динамического масштабирования с сохранением пропорций удобно комбинировать animate() и вычисленные коэффициенты:

rect.animate(1000).transform({ scale: 2 });
  • При анимации пропорции сохраняются автоматически, если используется одинаковый коэффициент для обеих осей.
  • Для адаптивной анимации к размеру окна можно пересчитывать коэффициенты при изменении размеров контейнера.

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