Установка Lottie Web в проект Svelte выполняется стандартно через npm-пакет, после чего становится доступен низкоуровневый API управления анимациями на основе JSON-экспорта из After Effects.
Библиотека подключается как обычный модуль:
npm install lottie-web
После установки становится доступен импорт
lottie-web/build/player/lottie_light или полноценный
lottie-web, в зависимости от требований к размеру бандла и
набору функций.
Интеграция строится вокруг DOM-контейнера, в который Lottie рендерит SVG, Canvas или HTML-разметку анимации.
<script>
import { onMount } from 'svelte';
import lottie from 'lottie-web';
let container;
let animation;
</script>
<div bind:this={container}></div>
Ключевой элемент — привязка bind:this, обеспечивающая
доступ к реальному DOM-узлу после монтирования компонента.
Запуск Lottie осуществляется только после появления DOM-элемента, что
соответствует жизненному циклу onMount.
<script>
import { onMount } from 'svelte';
import lottie from 'lottie-web';
import animationData from './animation.json';
let container;
let animation;
onMount(() => {
animation = lottie.loadAnimation({
container,
renderer: 'svg',
loop: true,
autoplay: true,
animationData
});
return () => {
animation?.destroy();
};
});
</script>
<div bind:this={container}></div>
Экземпляр анимации создаётся один раз и хранится в переменной для последующего управления.
Объект, возвращаемый loadAnimation, предоставляет набор
методов управления состоянием воспроизведения.
play() — запуск воспроизведенияpause() — приостановкаstop() — остановка и сброс к началуdestroy() — полное удаление экземпляраsetSpeed(value) — изменение скорости
воспроизведенияgoToAndPlay(frame) — переход к кадру с
воспроизведениемgoToAndStop(frame) — переход к кадру с остановкойanimation.pause();
animation.setSpeed(1.5);
animation.play();
Svelte позволяет связывать параметры Lottie с реактивными переменными, обеспечивая динамическое изменение поведения анимации.
<script>
import { onMount } from 'svelte';
import lottie from 'lottie-web';
import animationData from './animation.json';
let container;
let animation;
export let speed = 1;
export let isPlaying = true;
onMount(() => {
animation = lottie.loadAnimation({
container,
renderer: 'svg',
loop: true,
autoplay: false,
animationData
});
return () => animation?.destroy();
});
$: if (animation) {
animation.setSpeed(speed);
if (isPlaying) {
animation.play();
} else {
animation.pause();
}
}
</script>
<div bind:this={container}></div>
Реактивные выражения Svelte обеспечивают синхронизацию состояния анимации с внешними параметрами без ручного контроля обновлений.
Более инкапсулированный подход реализуется через actions, позволяющие привязать Lottie к любому DOM-элементу декларативно.
// lottieAction.js
import lottie from 'lottie-web';
export function lottieAction(node, params) {
let animation = lottie.loadAnimation({
container: node,
renderer: params.renderer || 'svg',
loop: params.loop ?? true,
autoplay: params.autoplay ?? true,
animationData: params.animationData
});
return {
update(newParams) {
animation.destroy();
animation = lottie.loadAnimation({
container: node,
...newParams
});
},
destroy() {
animation.destroy();
}
};
}
Использование в компоненте:
<script>
import { lottieAction } from './lottieAction.js';
import animationData from './animation.json';
let params = {
renderer: 'svg',
loop: true,
autoplay: true,
animationData
};
</script>
<div use:lottieAction={params}></div>
Actions позволяют отделить логику управления анимацией от структуры компонента.
Часто требуется динамическая замена JSON-анимации без пересоздания DOM-структуры компонента.
<script>
import { onMount } from 'svelte';
import lottie from 'lottie-web';
import animA from './a.json';
import animB from './b.json';
let container;
let animation;
let current = animA;
function load(anim) {
animation?.destroy();
animation = lottie.loadAnimation({
container,
renderer: 'svg',
loop: true,
autoplay: true,
animationData: anim
});
}
onMount(() => {
load(current);
return () => animation?.destroy();
});
function switchAnim() {
current = current === animA ? animB : animA;
load(current);
}
</script>
<div bind:this={container}></div>
Пересоздание экземпляра является наиболее надёжным способом смены данных анимации.
В средах с серверным рендерингом доступ к window и DOM
отсутствует, что требует условной инициализации.
<script>
import { browser } from '$app/environment';
import { onMount } from 'svelte';
import lottie from 'lottie-web';
let container;
onMount(() => {
if (!browser) return;
const animation = lottie.loadAnimation({
container,
renderer: 'svg',
loop: true,
autoplay: true,
animationData: {}
});
return () => animation.destroy();
});
</script>
<div bind:this={container}></div>
Инициализация строго ограничивается клиентской средой.
SVG-рендеринг обеспечивает высокое качество, но при сложных анимациях нагрузка на DOM может возрастать.
Применяются следующие подходы:
renderer: 'canvas' для тяжёлых сценautoplay для ленивой загрузкиif (animation) return;
Lottie предоставляет события жизненного цикла, интегрируемые с Svelte-реактивностью.
animation.addEventListener('complete', () => {
console.log('анимация завершена');
});
animation.addEventListener('loopComplete', () => {
console.log('цикл завершён');
});
Обработка событий позволяет синхронизировать анимацию с состоянием интерфейса.
Часто создаётся специализированный компонент-обёртка, принимающий параметры анимации как props.
<script>
import { onMount, onDestroy } from 'svelte';
import lottie from 'lottie-web';
export let animationData;
export let loop = true;
export let autoplay = true;
export let renderer = 'svg';
let container;
let animation;
onMount(() => {
animation = lottie.loadAnimation({
container,
animationData,
loop,
autoplay,
renderer
});
});
onDestroy(() => {
animation?.destroy();
});
</script>
<div bind:this={container}></div>
Такой слой упрощает повторное использование и стандартизирует поведение анимаций в интерфейсе.
Использование Lottie в Svelte обычно сводится к нескольким устойчивым моделям:
onMountКаждый подход выбирается в зависимости от степени переиспользования, сложности интерфейса и требований к производительности.