一、核心概念与适用场景
1. React Transition Group
- 定位:React 官方推荐的基础过渡动画库,专注于组件挂载/卸载和状态切换时的过渡效果,本身不直接提供 CSS 动画,而是提供动画生命周期钩子。
- 核心优势:轻量、无依赖、与 React 生命周期深度结合,适合简单的过渡动画(如弹窗显隐、列表项增删)。
- 适用场景:基础的进入/退出动画、列表过渡、路由切换过渡。
2. Framer Motion
- 定位:功能全面的 React 动画库,支持从简单过渡到复杂的手势、弹簧动画、路径动画等,API 简洁且声明式。
- 核心优势:开箱即用的动画效果、支持手势(拖拽/缩放)、SVG 动画、布局动画,学习成本低,适合快速实现丰富的交互动画。
- 适用场景:复杂交互动画(如拖拽、hover 效果)、页面转场、SVG 动画、微交互。
3. Lottie React
- 定位:Airbnb 出品的 Lottie 动画库的 React 封装,用于播放 AE (After Effects) 导出的 JSON 格式动画文件。
- 核心优势:还原设计师制作的高精度动画(如动效图标、品牌动画),无需前端手写关键帧,跨平台兼容。
- 适用场景:高精度视觉动画(如启动页动画、加载动画、营销页动效)、设计师定制的复杂动画。
二、具体使用示例
1. React Transition Group
前置依赖
bash
npm install react-transition-group
示例:组件显隐过渡
jsx
import { useState } from 'react';
import { CSSTransition } from 'react-transition-group';
import './styles.css';
const TransitionDemo = () => {
const [show, setShow] = useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>切换显隐</button>
{/* CSSTransition 包裹需要动画的组件 */}
<CSSTransition
in={show} // 控制动画触发的状态
timeout={300} // 动画时长(ms)
classNames="fade" // CSS 类名前缀
unmountOnExit // 动画结束后卸载组件
appear={true} // 首次渲染时也触发动画
>
<div className="box">我是过渡动画的内容</div>
</CSSTransition>
</div>
);
};
export default TransitionDemo;
配套 CSS (styles.css)
css
/* 初始状态 */
.fade-enter {
opacity: 0;
transform: translateX(20px);
}
/* 进入动画 */
.fade-enter-active {
opacity: 1;
transform: translateX(0);
transition: all 300ms ease;
}
/* 退出初始状态 */
.fade-exit {
opacity: 1;
transform: translateX(0);
}
/* 退出动画 */
.fade-exit-active {
opacity: 0;
transform: translateX(20px);
transition: all 300ms ease;
}
.box {
width: 200px;
height: 100px;
background: #4285f4;
color: white;
padding: 20px;
margin-top: 20px;
}
2. Framer Motion
前置依赖
bash
npm install framer-motion
示例:基础显隐 + 手势动画
jsx
import { useState } from 'react';
import { motion } from 'framer-motion';
const FramerDemo = () => {
const [show, setShow] = useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>切换显隐</button>
{/* motion 包裹原生元素,直接声明动画属性 */}
{show && (
<motion.div
className="box"
// 初始状态
initial={{ opacity: 0, x: 20 }}
// 入场动画
animate={{ opacity: 1, x: 0 }}
// 离场动画
exit={{ opacity: 0, x: -20 }}
// 动画配置
transition={{ duration: 0.3 }}
// 手势交互:拖拽
drag
// 拖拽边界
dragConstraints={{ left: 0, right: 200, top: 0, bottom: 0 }}
// hover 效果
whileHover={{ scale: 1.05, backgroundColor: '#34a853' }}
// 点击效果
whileTap={{ scale: 0.95 }}
>
Framer Motion 动画
</motion.div>
)}
</div>
);
};
export default FramerDemo;
配套 CSS
css
.box {
width: 200px;
height: 100px;
background: #4285f4;
color: white;
padding: 20px;
margin-top: 20px;
cursor: move;
}
3. Lottie React
前置依赖
bash
npm install lottie-react
示例:播放 AE 导出的 JSON 动画
jsx
import { useState } from 'react';
import Lottie from 'lottie-react';
// 导入 AE 导出的 JSON 动画文件(可从 lottiefiles.com 下载示例)
import animationData from './animation.json';
const LottieDemo = () => {
const [isPlaying, setIsPlaying] = useState(true);
return (
<div>
<button onClick={() => setIsPlaying(!isPlaying)}>
{isPlaying ? '暂停' : '播放'}
</button>
{/* 渲染 Lottie 动画 */}
<Lottie
animationData={animationData}
loop={true} // 循环播放
autoplay={isPlaying} // 自动播放
speed={1} // 播放速度
style={{ width: 300, height: 300 }} // 动画尺寸
/>
</div>
);
};
export default LottieDemo;
提示:你可以从 LottieFiles 下载免费的 JSON 动画文件测试,替换示例中的
animation.json。
三、方案对比
| 特性 | React Transition Group | Framer Motion | Lottie React |
|---|---|---|---|
| 核心能力 | 基础过渡(挂载/卸载) | 全场景动画+交互 | 高精度视觉动画 |
| 学习成本 | 中等(需手写 CSS) | 低(声明式 API) | 极低(只需导入文件) |
| 包体积 | 小(~5KB) | 中等(~30KB) | 中等(~15KB) |
| 自定义程度 | 高(需手写 CSS/JS) | 极高(支持自定义动画) | 低(依赖设计文件) |
| 适用场景 | 简单过渡、列表动画 | 交互动画、页面转场 | 动效图标、营销动画 |
总结
- React Transition Group:适合需要轻量、基础的组件过渡动画,无额外依赖,需配合 CSS 手写动画逻辑。
- Framer Motion:React 动画的首选方案,覆盖从简单过渡到复杂交互的全场景,API 简洁且功能强大。
- Lottie React:专为还原设计师制作的高精度动画而生,无需前端手写关键帧,适合品牌动效、加载动画等场景。
选择建议:简单过渡用 React Transition Group,复杂交互用 Framer Motion,高精度视觉动画用 Lottie React。