Анимации Lottie основаны на векторной графике, что делает их изначально независимыми от разрешения экрана. Однако поведение в браузере зависит от выбранного рендера, контейнера и механизма масштабирования. Ключевая задача — согласовать внутреннюю систему координат анимации с реальными размерами DOM-элемента и плотностью пикселей устройства.
Базовая единица измерения Lottie — логическое пространство композиции, заданное в After Effects. При рендере это пространство проецируется либо в SVG, либо в Canvas, и именно на этом этапе возникают различия в масштабировании, резкости и производительности.
Современные экраны используют различную плотность пикселей, что
отражается через window.devicePixelRatio. При стандартной
отрисовке без учета DPR возможны артефакты:
При использовании Canvas-рендера важно учитывать увеличение внутреннего буфера:
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio || 1;
canvas.width = container.clientWidth * dpr;
canvas.height = container.clientHeight * dpr;
canvas.style.width = `${container.clientWidth}px`;
canvas.style.height = `${container.clientHeight}px`;
ctx.scale(dpr, dpr);
SVG-рендер в большинстве случаев обрабатывает плотность пикселей
автоматически, однако визуальная четкость зависит от корректной работы
viewBox и preserveAspectRatio.
SVG обеспечивает автоматическое масштабирование через
viewBox. Основные характеристики:
Механизм масштабирования базируется на атрибутах контейнера:
lottie.loadAnimation({
container: element,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'animation.json',
rendererSettings: {
preserveAspectRatio: 'xMidYMid meet'
}
});
preserveAspectRatio определяет поведение при
несоответствии пропорций контейнера и композиции. Значения
meet и slice задают стратегию вписывания или
обрезки.
Canvas требует ручного управления масштабом. Основные особенности:
Canvas требует синхронизации размеров буфера и CSS-отображения. Несоответствие этих значений приводит к размытию.
Корректное поведение Lottie-анимаций зависит от размеров родительского контейнера. Основные подходы:
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.lottie-box {
width: 100%;
aspect-ratio: 16 / 9;
}
.lottie-wrapper {
position: absolute;
inset: 0;
}
Контейнер определяет базовую систему координат, от которой зависит пересчет размеров анимации.
Изменение размеров окна требует пересчета геометрии анимации. В Lottie Web отсутствует универсальный автоматический механизм адаптации, поэтому применяется ручное обновление.
Типовой подход:
let animation = lottie.loadAnimation({
container: element,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'animation.json'
});
window.addEventListener('resize', () => {
animation.resize();
});
Метод resize() инициирует перерасчет размеров SVG или
Canvas, однако поведение зависит от рендера и версии библиотеки.
Использование window.resize ограничено глобальными
изменениями окна. В компонентных интерфейсах контейнер может изменяться
независимо, что делает более точным ResizeObserver.
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
animation.resize();
}
});
observer.observe(container);
Этот механизм обеспечивает реакцию на любые изменения макета: скрытие панелей, изменение flex-структуры, динамическую загрузку контента.
В некоторых сценариях вызов resize() недостаточен. Это
характерно для:
В таких случаях используется пересоздание экземпляра:
animation.destroy();
animation = lottie.loadAnimation({
container: element,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'new-animation.json'
});
Пересоздание обеспечивает корректную пересборку внутренней структуры сцен.
SVG-рендер Lottie опирается на систему viewBox,
аналогичную SVG-спецификации. Параметр preserveAspectRatio
управляет тем, как композиция вписывается в контейнер.
Основные режимы:
xMidYMid meet — полное встраивание без обрезкиxMidYMid slice — заполнение с возможным обрезаниемnone — растяжение без сохранения пропорцийНесоответствие этого параметра приводит к смещению или деформации анимации при изменении размеров контейнера.
Мобильные браузеры добавляют дополнительные факторы:
Рекомендованные подходы:
vh и dvhResizeObserver вместо
resize.mobile-container {
height: 100dvh;
width: 100%;
}
Частые события resize могут приводить к перегрузке рендерера. Для стабилизации используется троттлинг:
let frame;
function onResize() {
cancelAnimationFrame(frame);
frame = requestAnimationFrame(() => {
animation.resize();
});
}
window.addEventListener('resize', onResize);
Дополнительно применяется разделение логики:
При Canvas-рендере важна синхронизация трех параметров:
canvas.widthcanvas.heightНесоответствие приводит к интерполяции и размытию изображения. Корректная модель масштабирования включает:
При работе в SPA-интерфейсах размеры контейнера могут изменяться каскадно. Основные проблемы:
Решение заключается в проверке валидности размеров перед обновлением:
function safeResize() {
const rect = container.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) return;
animation.resize();
}
В системах с grid и flex важно учитывать, что Lottie не управляет размерами самостоятельно. Поведение полностью зависит от родителя.
Типовые модели:
Пример адаптивной сетки:
.layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
Lottie-анимации в таком случае масштабируются вместе с ячейкой сетки, сохраняя пропорции при корректной настройке рендера.
Дополнительно к системному масштабированию используется API управления:
animation.setSpeed()animation.resize()animation.goToAndPlay()Хотя прямого метода setScale() нет, масштабирование
достигается через контейнер и rendererSettings.
При повторном использовании контейнера важно учитывать:
animation.destroy();
container.innerHTML = '';
Игнорирование очистки приводит к накоплению лишних SVG-узлов или canvas-контекстов, что ухудшает производительность при длительной работе интерфейса.