Lottie Web рендерит анимации либо в SVG, либо в Canvas, либо в HTML,
и в каждом режиме логика масштабирования привязана к контейнеру, в
который вставляется анимация. Базовый принцип работы заключается в том,
что размеры анимации не задаются внутри JSON как фиксированная геометрия
для отображения, а вычисляются относительно размеров DOM-элемента,
переданного в container.
const animation = lottie.loadAnimation({
container: document.querySelector('.animation'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'animation.json'
});
В этом случае контейнер становится единственным источником размеров. Любое изменение ширины или высоты DOM-элемента требует синхронного пересчёта рендера.
Ключевое поведение:
viewBoxВ основе Lottie лежит концепция исходного размера композиции,
заданного в After Effects. Эти размеры сохраняются в JSON как
w и h:
{
"w": 800,
"h": 600
}
При рендере Lottie сопоставляет:
И вычисляет коэффициент масштабирования:
scaleX = containerWidth / animationWidth
scaleY = containerHeight / animationHeight
В SVG-режиме это выражается через viewBox и
трансформации групп, в Canvas — через матрицу преобразования
контекста.
Поведение масштабирования зависит от настройки
rendererSettings, а также от внутреннего режима SVG.
На уровне SVG ключевую роль играет атрибут:
preserveAspectRatio="xMidYMid meet"
Lottie использует аналогичную модель:
meet — полное сохранение пропорцийslice — заполнение контейнера с обрезкойВ JavaScript API явного параметра preserveAspectRatio
нет, но поведение можно косвенно контролировать через CSS и размеры
контейнера.
Наиболее стабильный способ масштабирования Lottie-анимаций — управление контейнером через CSS:
.animation {
width: 100%;
height: 100%;
}
или в адаптивных макетах:
.animation {
width: 50vw;
height: 50vh;
}
SVG внутри контейнера автоматически подстраивается, поскольку Lottie
задаёт width: 100%; height: 100% на внутренний
SVG-элемент.
Важно, что отсутствие явной высоты у контейнера приводит к нулевой геометрии, что полностью ломает рендер.
Lottie Web не всегда автоматически реагирует на изменение размеров DOM-элемента. В ряде случаев требуется принудительный пересчёт:
window.addEventListener('resize', () => {
animation.resize();
});
Метод resize() инициирует:
При частых изменениях размеров использование resize без
оптимизации приводит к избыточным перерасчётам, поэтому применяется
троттлинг:
let timeout;
window.addEventListener('resize', () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
animation.resize();
}, 100);
});
Более точный способ отслеживания контейнера —
ResizeObserver, который реагирует не на окно, а на
конкретный элемент:
const container = document.querySelector('.animation');
const observer = new ResizeObserver(() => {
animation.resize();
});
observer.observe(container);
Этот подход критически важен в интерфейсах, где контейнер меняет размеры независимо от окна:
SVG-рендер Lottie использует внутреннюю систему групп
<g> с трансформациями:
Это означает, что:
Особенность: при резких изменениях размера возможны микросмещения из-за субпиксельного округления.
При использовании Canvas (renderer: 'canvas')
масштабирование включает пересчёт devicePixelRatio:
const animation = lottie.loadAnimation({
container: document.querySelector('.animation'),
renderer: 'canvas',
loop: true,
autoplay: true,
path: 'animation.json',
rendererSettings: {
clearCanvas: true,
progressiveLoad: false
}
});
Canvas-режим:
window.devicePixelRatioКорректная стратегия — всегда задавать размеры через CSS, а не через атрибуты canvas вручную.
Альтернативный подход — не менять размер контейнера, а масштабировать его через CSS transform:
.animation-wrapper {
transform: scale(1.5);
transform-origin: center;
}
В этом случае:
Преимущество — высокая производительность при анимациях интерфейса.
Недостаток — возможное размывание при Canvas-рендере.
В сложных интерфейсах используется комбинированный подход:
resize()max-width / max-height.animation {
width: 100%;
max-width: 600px;
aspect-ratio: 4 / 3;
}
Такой подход обеспечивает:
При изменении размеров контейнера важно учитывать точку привязки.
SVG-рендер использует центр композиции как базовую точку масштабирования. Если контейнер не центрирован визуально, возможны смещения.
Для стабилизации используется:
.animation {
display: flex;
align-items: center;
justify-content: center;
}
Это фиксирует визуальный центр относительно контейнера и предотвращает «прыжки» при resize.
В интерфейсах, где контейнер изменяет размеры из-за контента, возникает необходимость постоянной синхронизации:
В таких случаях ResizeObserver становится обязательным
инструментом, поскольку window.resize не отражает локальные
изменения.
const observer = new ResizeObserver(() => {
animation.resize();
});
observer.observe(document.querySelector('.panel'));
Часто встречающиеся ошибки связаны не с Lottie, а с контейнером:
position: absolute без размеровmin-heightresize() при динамическом
измененииКаждая из этих проблем приводит к рассинхронизации между JSON-композицией и реальным DOM-рендером.
Устойчивое масштабирование достигается при соблюдении трёх условий:
ResizeObserver или контролируемый
resizeaspect-ratio или
эквивалент)При такой конфигурации Lottie Web перестаёт зависеть от внешнего контекста и работает как предсказуемый слой в интерфейсной системе, где размер анимации всегда является производной от DOM-геометрии, а не от внутренней логики библиотеки