当前位置: 首页 > news >正文

framer-motion:React 动画库完全指南

1 概述:现代 React 动画解决方案

framer-motion 是一个功能强大的开源动画库,专为 React 应用设计,同时支持 Vanilla JS 和其他框架。作为目前 React 生态中最流行的动画解决方案之一,它以 简洁的 API高性能的混合动画引擎丰富的交互能力 著称,每周 npm 下载量超过 450 万次。

Motion 的核心优势在于 降低复杂动画的实现门槛:通过声明式 API,开发者无需深入掌握动画原理即可创建流畅的过渡效果、手势交互和滚动动画。其混合引擎结合了 JavaScript 动画的灵活性和浏览器原生 API(如 WAAPI)的性能优势,确保在各种设备上实现 60 FPS 动画。

核心功能 包括:

  • 基础动画(淡入淡出、缩放、旋转等)
  • 关键帧动画与序列控制
  • 手势交互(拖拽、悬停、点击)
  • 滚动触发动画
  • 布局动画(自动处理元素位置变化)
  • SVG 路径动画
  • 3D 动画支持(通过 framer-motion-3d 包)
  • TypeScript 类型安全

2 安装与配置:快速上手

2.1 环境要求

Motion 12.x 要求 React 18 或更高版本;若使用 React 19,需安装 alpha 版本:

# React 18
npm install framer-motion
# React 19(实验性)
npm install framer-motion@12.0.0-alpha.0

2.2 基础配置

在 TypeScript React 项目中,直接导入 motion 组件即可使用,无需额外配置:

import { motion } from 'framer-motion/react'const App = () => (<motion.divinitial={{ opacity: 0 }}animate={{ opacity: 1 }}transition={{ duration: 0.5 }}>Hello Motion!</motion.div>
)

注意:对于纯客户端渲染项目,可导入 framer-motion/react-client 以优化性能:

import { motion } from 'framer-motion/react-client'

3 核心概念:动画的基本构成

3.1 motion 组件

Motion 提供了封装好的 HTML/SVG 元素(如 motion.divmotion.buttonmotion.svg),这些组件继承了原元素的所有属性,并新增动画相关 props:

属性名作用示例值
initial初始状态(组件挂载时){ opacity: 0, x: -50 }
animate目标状态(触发动画){ opacity: 1, x: 0 }
exit退出状态(组件卸载时){ opacity: 0, scale: 0.8 }
transition动画过渡参数{ duration: 0.3, type: 'spring' }
variants预定义动画状态集合{ hidden: {...}, visible: {...} }

3.2 动画状态与过渡

动画的本质是 状态变化,Motion 通过 initialanimate 的状态插值实现过渡效果。例如,实现元素从左侧滑入并淡入:

const SlideIn = () => (<motion.divclassName="box"initial={{ opacity: 0, x: -100 }} // 初始:透明且向左偏移 100pxanimate={{ opacity: 1, x: 0 }}   // 目标:不透明且回到原位transition={{ type: 'spring',  // 弹簧动画stiffness: 300,  // 弹簧刚度damping: 20      // 阻尼(弹性)}}>滑入动画</motion.div>
)

3.3 Variants:状态化动画管理

Variants 允许将动画状态抽象为可复用的对象,便于管理复杂状态逻辑:

// 定义变体
const cardVariants = {hidden: { opacity: 0, scale: 0.9 },  // 隐藏状态visible: { opacity: 1, scale: 1,transition: { duration: 0.5,staggerChildren: 0.2  // 子元素动画延迟} },pressed: { scale: 0.95 }  // 按压状态
}// 使用变体
const AnimatedCard = ({ children }) => (<motion.divvariants={cardVariants}initial="hidden"       // 初始状态animate="visible"      // 触发显示动画whileTap="pressed"    // 点击时触发按压状态>{children}{/* 子元素自动继承变体状态 */}<motion.p variants={cardVariants}>子元素动画</motion.p></motion.div>
)

4 常用动画示例:从基础到交互

4.1 基础属性动画

实现颜色、尺寸、旋转等 CSS 属性动画:

const PropertyAnimation = () => (<motion.divstyle={{ width: 100, height: 100, backgroundColor: '#3498db' }}animate={{rotate: 360,          // 旋转 360°scale: [1, 1.2, 1],   // 缩放关键帧:正常 → 放大 → 正常backgroundColor: '#e74c3c'  // 颜色过渡}}transition={{duration: 2,repeat: Infinity,     // 无限循环repeatType: 'reverse' // 反向重复}}/>
)

4.2 手势交互动画

利用 whileHoverwhileTapdrag 等 props 实现交互反馈:

const GestureDemo = () => (<motion.divstyle={{ width: 150, height: 150, backgroundColor: '#2ecc71' }}whileHover={{ scale: 1.1,          // 悬停时放大boxShadow: '0 10px 20px rgba(0,0,0,0.2)' }}whileTap={{ scale: 0.9 }}  // 点击时缩小drag                       // 允许拖拽dragConstraints={{         // 拖拽范围限制left: -100,right: 100,top: -100,bottom: 100}}dragElastic={0.3}          // 拖拽弹性/>
)

4.3 滚动触发动画

使用 useScrolluseTransform 实现滚动位置关联动画:

import { useScroll, useTransform, motion } from 'framer-motion'const ScrollAnimation = () => {// 获取滚动进度(0 → 1)const { scrollYProgress } = useScroll()// 将滚动进度转换为旋转角度(0 → 360°)const rotate = useTransform(scrollYProgress, [0, 1], [0, 360])return (<motion.divstyle={{ position: 'fixed',rotate,  // 应用旋转动画fontSize: 32}}>滚动旋转</motion.div>)
}

4.4 布局动画

通过 layout 属性自动处理元素位置/尺寸变化的过渡:

import { useState } from 'react'
import { motion } from 'framer-motion'const LayoutAnimation = () => {const [toggle, setToggle] = useState(false)return (<div className="container"><motion.button onClick={() => setToggle(!toggle)}whileTap={{ scale: 0.95 }}>切换布局</motion.button><motion.div layout  // 启用布局动画className="box"style={{ width: toggle ? 200 : 100,height: toggle ? 200 : 100,backgroundColor: '#f39c12'}}/></div>)
}

5 高级特性:构建复杂动效

5.1 动画序列与时间线

使用 staggersequence 控制多元素动画顺序:

import { stagger, motion } from 'framer-motion'// 定义 staggered 变体
const listVariants = {visible: {transition: {staggerChildren: 0.1,  // 子元素延迟 0.1s 依次动画staggerDirection: 1    // 正向(1)或反向(-1)}}
}const itemVariants = {hidden: { opacity: 0, y: 20 },visible: { opacity: 1, y: 0 }
}const StaggerList = () => (<motion.ul variants={listVariants} initial="hidden" animate="visible">{['Item 1', 'Item 2', 'Item 3'].map((item, i) => (<motion.li key={i} variants={itemVariants}transition={{ duration: 0.3 }}>{item}</motion.li>))}</motion.ul>
)

5.2 动态值与变换

通过 useMotionValueuseTransform 创建自定义动态值:

import { useMotionValue, useTransform, motion } from 'framer-motion'const CustomMotionValue = () => {// 创建动态值(初始值 0)const x = useMotionValue(0)// 将 x(-200 → 200)转换为旋转角度(-45° → 45°)const rotate = useTransform(x, [-200, 200], [-45, 45])return (<motion.divstyle={{ x, rotate }}  // 应用 x 和 rotatedrag="x"              // 仅允许 X 轴拖拽dragConstraints={{ left: -200, right: 200 }}>拖拽旋转</motion.div>)
}

5.3 SVG 与路径动画

Motion 支持 SVG 路径动画,通过 pathLengthpathOffset 控制路径绘制:

import { motion } from 'framer-motion'const PathAnimation = () => (<svg width="200" height="200" viewBox="0 0 200 200"><motion.pathd="M 50,100 Q 100,50 150,100 T 250,100"  // 贝塞尔曲线stroke="blue"strokeWidth="4"fill="none"initial={{ pathLength: 0 }}  // 初始:路径长度 0(不可见)animate={{ pathLength: 1 }}  // 目标:路径长度 1(完全绘制)transition={{ duration: 2 }}/></svg>
)

6 性能优化:确保流畅体验

6.1 硬件加速与渲染优化

优先使用 transformopacity 属性动画,避免触发浏览器重排:

// 推荐:使用 transform(GPU 加速)
<motion.div animate={{ x: 100, scale: 1.2 }} />// 避免:直接修改 width/height(触发重排)
<motion.div animate={{ width: 200 }} />  // 性能较差

6.2 减少不必要的动画

通过 useReducedMotion 尊重用户系统设置(如"减少动画"模式):

import { useReducedMotion } from 'framer-motion'const ResponsiveAnimation = () => {const shouldReduceMotion = useReducedMotion()return (<motion.divanimate={{ x: shouldReduceMotion ? 0 : 100 }}  // 减少动画模式下禁用位移transition={{ duration: shouldReduceMotion ? 0 : 0.5 }}/>)
}

6.3 优化变体解析

Motion 11+ 支持 延迟解析变体,提升复杂动画性能:

// 优化前:变体在组件挂载时立即解析
const variants = {visible: { opacity: 1, x: 0 }
}// 优化后:使用函数延迟解析(仅在动画触发时执行)
const variants = {visible: () => ({ opacity: 1, x: 0 })
}

7 实际应用场景:从基础到复杂

7.1 导航菜单过渡

实现侧边栏菜单滑入滑出动画:

import { useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'const Sidebar = () => {const [isOpen, setIsOpen] = useState(false)return (<><button onClick={() => setIsOpen(!isOpen)}>{isOpen ? '关闭' : '打开'}菜单</button>{/* AnimatePresence:监听子元素卸载动画 */}<AnimatePresence>{isOpen && (<motion.navinitial={{ x: '-100%' }}  // 初始:完全隐藏在左侧animate={{ x: 0 }}       // 目标:滑入视口exit={{ x: '-100%' }}    // 退出:滑出视口transition={{ type: 'spring', stiffness: 300 }}className="sidebar"><ul><li>首页</li><li>关于</li><li>联系</li></ul></motion.nav>)}</AnimatePresence></>)
}

7.2 数据卡片交互

结合手势和布局动画实现卡片悬停/点击效果:

const DataCard = ({ title, value }) => (<motion.divclassName="card"whileHover={{ y: -5,  // 上移 5pxboxShadow: '0 10px 25px rgba(0,0,0,0.1)' }}whileTap={{ scale: 0.98 }}  // 点击缩小layout  // 支持尺寸变化动画transition={{ type: 'spring', stiffness: 400 }}><h3>{title}</h3><p className="value">{value}</p></motion.div>
)

8 总结:Motion 的价值与最佳实践

Motion 作为现代 React 动画库,通过 声明式 API高性能引擎,大幅降低了复杂动画的实现成本。核心优势包括:

  • 易用性:无需深入动画原理,通过 props 快速实现动效
  • 灵活性:支持从简单过渡到复杂序列的全场景动画需求
  • 性能:混合引擎结合硬件加速,确保流畅体验
  • TypeScript 友好:内置类型定义,提供类型安全

最佳实践

  1. 优先使用 variants 管理多状态动画,提高可维护性
  2. 避免过度动画,关键交互(如按钮、卡片)才添加动效
  3. 始终测试 “减少动画” 模式下的体验
  4. 复杂场景使用 AnimatePresence 管理组件生命周期动画

通过合理使用 Motion,开发者可以为用户界面注入生动的交互体验,同时保持代码的可维护性和性能。

http://www.dtcms.com/a/410669.html

相关文章:

  • 网站开发 面试 适当吹牛建设工程质量监理协会网站
  • BI磁吸布局 (2) 基于react-grid-layout扩展的布局方式
  • python(42) : 监听本地文件夹上传到服务器指定目录
  • c 网站建设报告外贸企业网站推广
  • 成都网站建设熊掌号网站 域名 授权服务器 分布式
  • 使用python+flask设置挡板
  • WinCC监控系统实战解析:打通物联网网关的关键步骤
  • 阜宁做网站需要多少钱厦门彩页设计
  • 【Android】 android suspend/resume总结(3)
  • 【Android】Android项目目录结构及其作用
  • 动易网站首页制作移动网站排名教程
  • 网站开发和ipv6便宜网站建设 优帮云
  • 前端笔记:HTML output标签介绍及用法
  • Atlas Mapper 教程系列 (6/10):Spring Boot 集成与自动配置
  • 挂马网站现象基于PHP网站开发的管理系统设计与开发
  • DSP28335开发中的Flash与RAM模式切换详解
  • 海珠建网站公石狮网站建设公司哪家好
  • 网站建设电话销售录音建行个人网上登录入口
  • Python全栈项目:基于深度学习的语音识别系统
  • 语音识别-流式和非流式实现方式
  • 网站被攻击 是vps问题还是dz程序建设网站的经验
  • uniapp中pinia(setup语法)使用流程
  • SimpleBEV:改进的激光雷达-摄像头融合架构用于三维目标检测
  • 一个网站制作流程qq快速登录入口
  • Flash Attention学习笔记
  • 解决 QGraphicsDropShadowEffect 导致的 UI 持续刷新
  • 用 LoRA 微调 Qwen3-0.6B 模型,打造专属宠物商店智能客服
  • 建搜索引擎网站衡东网络推广公司
  • Go test 命令完整指南:从基础到高级用法
  • apifox认证登录自动化