Реализация Lottie-анимаций на сайте
Lottie — формат JSON для векторных анимаций, экспортированных из Adobe After Effects через плагин Bodymovin. Анимации воспроизводятся через JavaScript или нативные рендереры, сохраняя качество на любом DPI. Основное применение — иконки, иллюстрации, лоадеры, пустые состояния (empty states).
Установка
# Лёгкий плеер — только SVG-рендерер, ~60 КБ gzip
npm install @lottiefiles/dotlottie-react
# Альтернатива — lottie-react (полный рендерер, ~180 КБ gzip)
npm install lottie-react
DotLottie — более новый формат (.lottie, бинарный zip), рекомендуется для новых проектов: в 10 раз легче JSON эквивалента.
Базовый компонент
// components/LottieAnimation.tsx
import { DotLottieReact } from '@lottiefiles/dotlottie-react'
interface LottieAnimationProps {
src: string // URL или путь к .lottie/.json
loop?: boolean
autoplay?: boolean
className?: string
onComplete?: () => void
}
export function LottieAnimation({
src,
loop = true,
autoplay = true,
className,
onComplete,
}: LottieAnimationProps) {
return (
<DotLottieReact
src={src}
loop={loop}
autoplay={autoplay}
className={className}
onComplete={onComplete}
/>
)
}
Управление воспроизведением
// components/ControlledLottie.tsx
import { useRef, useState } from 'react'
import { DotLottieReact, DotLottie } from '@lottiefiles/dotlottie-react'
export function ControlledLottie({ src }: { src: string }) {
const [dotLottie, setDotLottie] = useState<DotLottie | null>(null)
const play = () => dotLottie?.play()
const pause = () => dotLottie?.pause()
const stop = () => dotLottie?.stop()
const setSpeed = (speed: number) => dotLottie?.setSpeed(speed)
const seekTo = (frame: number) => dotLottie?.setFrame(frame)
return (
<div>
<DotLottieReact
src={src}
loop={false}
autoplay={false}
dotLottieRefCallback={setDotLottie}
/>
<div className="flex gap-2 mt-4">
<button onClick={play}>Играть</button>
<button onClick={pause}>Пауза</button>
<button onClick={stop}>Стоп</button>
<button onClick={() => setSpeed(2)}>2x</button>
</div>
</div>
)
}
Анимация при наведении (интерактивная иконка)
// components/AnimatedIcon.tsx
import { useRef, useState } from 'react'
import { DotLottieReact, DotLottie } from '@lottiefiles/dotlottie-react'
interface AnimatedIconProps {
src: string
size?: number
hoverToPlay?: boolean
}
export function AnimatedIcon({ src, size = 32, hoverToPlay = true }: AnimatedIconProps) {
const [dotLottie, setDotLottie] = useState<DotLottie | null>(null)
const handleMouseEnter = () => {
if (hoverToPlay && dotLottie) {
dotLottie.stop()
dotLottie.play()
}
}
return (
<div
onMouseEnter={handleMouseEnter}
style={{ width: size, height: size }}
className="cursor-pointer"
>
<DotLottieReact
src={src}
loop={false}
autoplay={false}
dotLottieRefCallback={setDotLottie}
/>
</div>
)
}
Лоадер на Lottie
// components/LottieLoader.tsx
import { DotLottieReact } from '@lottiefiles/dotlottie-react'
export function PageLoader() {
return (
<div className="fixed inset-0 flex items-center justify-center bg-white z-50">
<DotLottieReact
src="/animations/loader.lottie"
loop
autoplay
style={{ width: 120, height: 120 }}
/>
</div>
)
}
// Использование со Suspense/загрузкой данных
export function DataLoader({ isLoading }: { isLoading: boolean }) {
if (!isLoading) return null
return (
<div className="flex justify-center py-12">
<DotLottieReact
src="/animations/spinner.lottie"
loop
autoplay
style={{ width: 64, height: 64 }}
/>
</div>
)
}
Оптимизация загрузки
Lottie-файлы можно предзагружать и кешировать:
// lib/lottie-cache.ts
const cache = new Map<string, object>()
export async function preloadLottie(src: string): Promise<void> {
if (cache.has(src)) return
const res = await fetch(src)
const data = await res.json()
cache.set(src, data)
}
export function getCachedLottie(src: string): object | undefined {
return cache.get(src)
}
Для JSON-формата через lottie-react можно импортировать анимацию напрямую — тогда bundler включит её в chunk:
import Lottie from 'lottie-react'
import successAnimation from '@/animations/success.json'
export function SuccessAnimation() {
return (
<Lottie
animationData={successAnimation}
loop={false}
style={{ width: 200, height: 200 }}
/>
)
}
Для .lottie-формата используйте CDN или /public-папку — не импортируйте напрямую, бинарный файл не обрабатывается стандартными bundler-лоадерами без настройки.
Типичные сроки
Интеграция готовых анимаций из LottieFiles.com — 2–4 часа. Полная обвязка с кешированием, управлением воспроизведением и адаптивным размером — 1 рабочий день.







