Векторная графика в SVG строится на координатной системе, где каждый
элемент располагается относительно начальной точки холста. Ключевую роль
в позиционировании играет атрибут viewBox, определяющий
внутреннюю систему координат изображения:
<svg viewBox="0 0 800 400">
Значения 0 0 800 400 задают область координат: левый
верхний угол соответствует (0,0), правый нижний — (800,400). Любые
фигуры внутри SVG размещаются именно в этой системе, независимо от
фактического размера элемента на странице.
<rect x="100" y="50" width="200" height="100" />
Позиционирование прямоугольника происходит строго в рамках viewBox, а масштабирование SVG-контейнера не изменяет его внутреннюю геометрию.
Атрибут preserveAspectRatio определяет поведение
масштабирования SVG при изменении размеров контейнера.
<svg viewBox="0 0 800 400" preserveAspectRatio="xMidYMid meet">
Разбор ключевых значений:
xMin, xMid, xMax —
горизонтальное выравниваниеYMin, YMid, YMax —
вертикальное выравниваниеmeet — сохранение пропорций с возможным появлением
полейslice — заполнение контейнера с обрезкойКомбинация xMidYMid фиксирует центрирование по обеим
осям, что особенно важно при анимации SVG, чтобы движение не смещалось
относительно визуального центра.
Библиотека Vivus работает с путями SVG (<path>)
через манипуляцию свойствами stroke-dasharray и
stroke-dashoffset. Позиция анимации зависит не только от
координат, но и от геометрии самого пути.
<path d="M10 10 L200 10" />
При инициализации Vivus вычисляет длину пути и применяет маскирование:
new Vivus('svg', {
duration: 100,
type: 'delayed'
});
Если SVG не центрирован, визуальное «рисование» может смещаться
относительно макета из-за несоответствия bounding box
(getBBox) и ожидаемой системы координат.
Для точного позиционирования используется вычисление ограничивающего прямоугольника элемента:
const path = document.querySelector('path');
const box = path.getBBox();
const cx = box.x + box.width / 2;
const cy = box.y + box.height / 2;
Полученные координаты позволяют выровнять группу элементов относительно центра:
const svg = document.querySelector('svg');
svg.querySelector('g').setAttribute(
'transform',
`translate(${-cx}, ${-cy})`
);
Использование <g> (группы) позволяет смещать сразу
несколько путей без изменения их индивидуальной геометрии.
Vivus рассчитывает анимацию в локальных координатах SVG. Любые
трансформации (transform) влияют на визуальное восприятие,
но не всегда синхронизируются с расчетом длины пути.
Типичная проблема проявляется при:
transform: scale()translate()<g> группКорректная последовательность структуры SVG:
<svg viewBox="0 0 800 400">
<g transform="translate(0,0)">
<path d="..." />
</g>
</svg>
Любое смещение до инициализации Vivus влияет на расчет начальных состояний анимации.
При работе с множеством <path> возникает
необходимость согласования их относительных координат.
<path d="M0 0 L100 0" />
<path d="M0 20 L100 20" />
<path d="M0 40 L100 40" />
Если требуется центрирование всей группы, используется общий bounding box:
const paths = document.querySelectorAll('path');
let minX = Infinity;
let minY = Infinity;
let maxX = -Infinity;
let maxY = -Infinity;
paths.forEach(p => {
const b = p.getBBox();
minX = Math.min(minX, b.x);
minY = Math.min(minY, b.y);
maxX = Math.max(maxX, b.x + b.width);
maxY = Math.max(maxY, b.y + b.height);
});
const centerX = (minX + maxX) / 2;
const centerY = (minY + maxY) / 2;
Далее выполняется смещение всей группы:
const group = document.querySelector('g');
group.setAttribute(
'transform',
`translate(${-centerX}, ${-centerY})`
);
При встраивании SVG в адаптивный интерфейс возникает несоответствие между контейнером и внутренней системой координат.
Ключевой момент — разделение:
width, height)viewBox)svg {
width: 100%;
height: auto;
}
В таком режиме Vivus продолжает работать в фиксированной системе
координат, заданной viewBox, что исключает пересчет
анимации при изменении размера экрана.
Vivus начинает отрисовку пути с первой точки контура
(M). Однако визуальный старт может отличаться от
геометрического центра фигуры.
<path d="M50 50 L300 50 L300 200" />
Если требуется визуальное центрирование анимации, используется предварительное преобразование пути:
<g>Толщина линии влияет на визуальное положение пути, хотя геометрия остается неизменной.
path {
stroke-width: 8;
}
При больших значениях stroke-width центр линии смещается
относительно математической кривой. Для компенсации используется:
path {
vector-effect: non-scaling-stroke;
}
Это фиксирует толщину линии при масштабировании и стабилизирует визуальное выравнивание.
Для сложных SVG-композиций (иконки, логотипы, сцены) используется комбинация подходов:
<g><svg viewBox="0 0 500 500">
<g transform="translate(-250 -250)">
<path d="..." />
<circle cx="..." cy="..." r="..." />
</g>
</svg>
Такое смещение приводит систему координат к центру (0,0), что упрощает дальнейшую анимацию в Vivus.
Vivus поддерживает различные типы анимации (delayed,
sync, oneByOne). Порядок отрисовки влияет на
восприятие композиции, особенно при несбалансированном расположении
элементов.
При oneByOne последовательность может визуально
«утягивать» композицию в сторону, если элементы распределены
асимметрично. В таких случаях применяется предварительное выравнивание
элементов внутри группы перед запуском анимации.
Хотя transform-origin относится к CSS, в SVG он может
влиять на поведение масштабирования контейнера:
svg {
transform-origin: center center;
}
При анимации контейнера вместе с Vivus важно учитывать, что внутренние координаты SVG не изменяются, и расхождение систем координат может приводить к визуальному смещению.
Перед применением Vivus часто выполняется нормализация SVG:
const bbox = svg.getBBox();
group.setAttribute(
'transform',
`translate(${-bbox.x}, ${-bbox.y})`
);
Такая подготовка обеспечивает стабильность анимации независимо от исходного редактора SVG.