在 Web 项目中使用 Lottie 动画有多种方式,以下是详细的实现方法:
1. 使用 lottie-web 库
安装:
bashnpm install lottie-web # 或 yarn add lottie-web
基本使用:
javascriptimport lottie from 'lottie-web'; // 方式1:从 URL 加载 const animation = lottie.loadAnimation({ container: document.getElementById('lottie-container'), renderer: 'svg', // 'svg', 'canvas', 'html' loop: true, autoplay: true, path: 'https://example.com/animation.json' }); // 方式2:从本地文件加载 import animationData from './animation.json'; const animation = lottie.loadAnimation({ container: document.getElementById('lottie-container'), renderer: 'svg', loop: true, autoplay: true, animationData: animationData });
2. 使用 LottieFiles Player(推荐)
HTML 方式:
html<script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script> <lottie-player src="https://example.com/animation.json" background="transparent" speed="1" style="width: 300px; height: 300px" loop autoplay> </lottie-player>
React 组件方式:
bashnpm install @lottiefiles/react-lottie-player # 或 yarn add @lottiefiles/react-lottie-player
jsximport { Player } from '@lottiefiles/react-lottie-player'; function MyComponent() { return ( <Player autoplay loop src="https://example.com/animation.json" style={{ height: '300px', width: '300px' }} /> ); }
3. 使用 react-lottie
安装:
bashnpm install react-lottie # 或 yarn add react-lottie
jsximport Lottie from 'react-lottie'; import animationData from './animation.json'; const defaultOptions = { loop: true, autoplay: true, animationData: animationData, rendererSettings: { preserveAspectRatio: 'xMidYMid slice' } }; function MyComponent() { return <Lottie options={defaultOptions} height={400} width={400} />; }
4. 动画控制
播放控制:
javascriptconst animation = lottie.loadAnimation({...}); // 播放 animation.play(); // 暂停 animation.pause(); // 停止 animation.stop(); // 设置播放速度 animation.setSpeed(1.5); // 设置播放方向 animation.setDirection(-1); // -1 反向,1 正向 // 跳转到指定帧 animation.goToAndStop(30, true); // true 表示帧数,false 表示时间 // 设置进度 animation.goToAndPlay(0.5, true); // 0.5 表示 50% 进度
事件监听:
javascriptanimation.addEventListener('complete', () => { console.log('Animation completed'); }); animation.addEventListener('loopComplete', () => { console.log('Animation loop completed'); }); animation.addEventListener('enterFrame', () => { console.log('Animation entered frame'); }); animation.addEventListener('config_ready', () => { console.log('Configuration ready'); }); animation.addEventListener('data_ready', () => { console.log('Data ready'); }); animation.addEventListener('DOMLoaded', () => { console.log('DOM loaded'); }); animation.addEventListener('destroy', () => { console.log('Animation destroyed'); });
5. 动态属性修改
修改颜色:
javascript// 使用 colorFilters animation.setColorFilter([ { keypath: 'layer1', color: '#FF0000' } ]); // 或者直接修改 JSON 数据 animationData.layers[0].shapes[0].c.k = [1, 0, 0, 1]; animation.destroy(); const newAnimation = lottie.loadAnimation({ container: document.getElementById('lottie-container'), animationData: animationData, renderer: 'svg', loop: true, autoplay: true });
修改文本:
javascript// 对于文本图层 animationData.layers.forEach(layer => { if (layer.ty === 1) { // 文本图层 layer.t.d.k[0].s.t = 'New Text'; } });
6. 性能优化
使用 Canvas 渲染:
javascriptconst animation = lottie.loadAnimation({ container: document.getElementById('lottie-container'), renderer: 'canvas', // Canvas 比 SVG 性能更好 loop: true, autoplay: true, path: 'animation.json', rendererSettings: { preserveAspectRatio: 'xMidYMid slice', clearCanvas: false, progressiveLoad: true, hideOnTransparent: true } });
懒加载:
javascript// 使用 Intersection Observer const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const animation = lottie.loadAnimation({ container: entry.target, renderer: 'svg', loop: true, autoplay: true, path: 'animation.json' }); observer.unobserve(entry.target); } }); }); document.querySelectorAll('.lottie-lazy').forEach(el => { observer.observe(el); });
7. 响应式处理
javascript// 监听窗口大小变化 const animation = lottie.loadAnimation({...}); window.addEventListener('resize', () => { animation.resize(); }); // 或者使用 CSS 媒体查询 #lottie-container { width: 100%; max-width: 500px; height: auto; } @media (max-width: 768px) { #lottie-container { max-width: 300px; } }
8. 与框架集成
Vue.js:
vue<template> <div ref="lottieContainer"></div> </template> <script> import lottie from 'lottie-web'; import animationData from './animation.json'; export default { mounted() { this.animation = lottie.loadAnimation({ container: this.$refs.lottieContainer, renderer: 'svg', loop: true, autoplay: true, animationData: animationData }); }, beforeDestroy() { this.animation.destroy(); } }; </script>
Angular:
typescriptimport { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core'; import lottie from 'lottie-web'; import * as animationData from './animation.json'; @Component({ selector: 'app-lottie', template: '<div #lottieContainer></div>' }) export class LottieComponent implements AfterViewInit { @ViewChild('lottieContainer', { static: true }) lottieContainer: ElementRef; ngAfterViewInit() { lottie.loadAnimation({ container: this.lottieContainer.nativeElement, renderer: 'svg', loop: true, autoplay: true, animationData: animationData }); } }
9. 错误处理
javascripttry { const animation = lottie.loadAnimation({ container: document.getElementById('lottie-container'), renderer: 'svg', loop: true, autoplay: true, path: 'animation.json' }); animation.addEventListener('data_failed', (error) => { console.error('Animation data failed to load:', error); // 显示降级内容 document.getElementById('lottie-container').innerHTML = '<img src="fallback.png" alt="Animation fallback">'; }); } catch (error) { console.error('Failed to load animation:', error); }
10. 最佳实践
- 使用 CDN 加速动画文件加载
- 为动画提供合适的占位符
- 实现降级方案(静态图片或 CSS 动画)
- 在组件卸载时清理动画实例
- 使用 Intersection Observer 实现懒加载
- 根据设备性能选择合适的渲染器
- 压缩和优化 JSON 文件大小
- 使用 Service Worker 缓存动画文件