名称: motion 描述: Motion (Framer Motion) React动画库。用于拖放、滚动动画、手势、SVG变形,或遇到包大小、复杂过渡、弹簧物理错误。
许可证: MIT
Motion动画库
概述
Motion (包: motion, 以前称为 framer-motion) 是行业标准的React动画库,被数千个应用程序在生产中使用。拥有30,200+ GitHub星和300+官方示例,它提供了声明式API,用最少的代码创建复杂的动画。
关键能力:
- 手势: 拖放、悬停、点击、平移、焦点,支持跨设备
- 滚动动画: 视口触发、滚动链接、视差效果
- 布局动画: FLIP技术用于平滑布局变化,共享元素过渡
- 弹簧物理: 自然、可定制的运动,基于物理的缓动
- SVG: 路径变形、线条绘制、属性动画
- 退出动画: AnimatePresence用于卸载过渡
- 性能: 硬件加速、ScrollTimeline API、包优化 (2.3 KB - 34 KB)
生产测试: React 19, Next.js 15, Vite 6, Tailwind v4
何时使用此技能
✅ 使用Motion当:
复杂交互:
- 拖放界面 (可排序列表、看板、滑块)
- 悬停状态带有缩放/旋转/颜色变化
- 点击反馈带有弹跳/挤压效果
- 平移手势用于移动友好控制
基于滚动的动画:
- 英雄部分带有视差层
- 滚动触发显示 (元素进入视口时淡入)
- 进度条链接到滚动位置
- 粘性头部带有滚动依赖变换
布局过渡:
- 路由之间的共享元素过渡 (卡片 → 详情页面)
- 扩展/折叠带有自动高度动画
- 网格/列表视图切换带有平滑重新定位
- 标签导航带有动画下划线
高级功能:
- SVG线条绘制动画
- 形状之间的路径变形
- 弹簧物理用于自然弹跳
- 编排序列 (交错显示)
- 模态对话框带有背景模糊
包优化:
- 需要2.3 KB动画库 (useAnimate mini)
- 想将Motion从34 KB减少到4.6 KB (LazyMotion)
❌ 不要使用Motion当:
- 简单列表动画 (使用
auto-animate代替: 3.28 KB vs 34 KB) - 静态内容 没有交互
- Cloudflare Workers (使用
framer-motionv12.23.24 解决方法 - 见已知问题) - 3D动画 (使用 Three.js 或 React Three Fiber 代替)
安装
最新稳定版本
bun add motion # 首选
# 或: npm install motion
# 或: yarn add motion
当前版本: 12.23.24 (验证于 2025-11-07)
Cloudflare Workers替代方案:
# 如果部署到Cloudflare Workers,使用 framer-motion
bun add framer-motion
# 或: npm install framer-motion
包信息
- 包大小:
- 完整
motion组件: ~34 KB 最小化+gzip LazyMotion+m组件: ~4.6 KBuseAnimatemini: 2.3 KB (最小的React动画库)useAnimate混合: 17 KB
- 完整
- 依赖: React 18+ 或 React 19+
- TypeScript: 原生支持包含 (不需要 @types 包)
核心概念
1. motion 组件
将任何HTML/SVG元素转换为可动画组件:
import { motion } from "motion/react"
// 基本动画
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
内容淡入并向上滑动
</motion.div>
// 手势控制
<motion.button
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
>
点击我
</motion.button>
属性:
initial: 起始状态 (对象或变体名称)animate: 目标状态 (对象或变体名称)exit: 卸载状态 (需要AnimatePresence)transition: 定时/缓动配置whileHover,whileTap,whileFocus: 手势状态whileInView: 视口触发动画drag: 启用拖放 (“x”, “y”, 或 true 用于两者)layout: 启用FLIP布局动画
2. 变体 (动画编排)
命名的动画状态,通过组件树传播:
const variants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 }
}
<motion.div variants={variants} initial="hidden" animate="visible">
内容
</motion.div>
对于高级编排 (staggerChildren, delayChildren, 动态变体),加载 references/core-concepts-deep-dive.md。
3. AnimatePresence (退出动画)
启用组件卸载时的动画:
import { AnimatePresence } from "motion/react"
<AnimatePresence>
{isVisible && (
<motion.div
key="modal"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
模态内容
</motion.div>
)}
</AnimatePresence>
关键规则:
- AnimatePresence 必须保持挂载 (不要包装在条件中)
- 所有子项 必须有唯一的
key属性 - AnimatePresence 包装条件,而不是相反
常见错误 (退出动画不会播放):
// ❌ 错误 - AnimatePresence 随条件卸载
{isVisible && (
<AnimatePresence>
<motion.div>内容</motion.div>
</AnimatePresence>
)}
// ✅ 正确 - AnimatePresence 保持挂载
<AnimatePresence>
{isVisible && <motion.div key="unique">内容</motion.div>}
</AnimatePresence>
4. 布局动画 (FLIP)
自动动画布局变化:
<motion.div layout>
{isExpanded ? <FullContent /> : <Summary />}
</motion.div>
特殊属性: layoutId (共享元素过渡), layoutScroll (可滚动容器), layoutRoot (固定定位)。
对于高级模式 (LayoutGroup, layoutId 编排),加载 references/core-concepts-deep-dive.md。
5. 滚动动画
// 视口触发
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
>
进入视口时淡入
</motion.div>
// 滚动链接 (视差)
import { useScroll, useTransform } from "motion/react"
const { scrollYProgress } = useScroll()
const y = useTransform(scrollYProgress, [0, 1], [0, -300])
<motion.div style={{ y }}>视差效果</motion.div>
对于高级滚动模式 (useScroll 偏移, useTransform 缓动, 视差层),加载 references/core-concepts-deep-dive.md。
6. 手势
<motion.div drag="x" dragConstraints={{ left: -200, right: 200 }}>
拖放我
</motion.div>
可用: whileHover, whileTap, whileFocus, whileDrag, whileInView, drag。
对于高级拖放控制 (动量, 弹性, 事件处理程序),加载 references/core-concepts-deep-dive.md。
7. 弹簧物理
<motion.div
animate={{ x: 100 }}
transition={{ type: "spring", stiffness: 100, damping: 10 }}
/>
常见预设: 弹跳 { stiffness: 300, damping: 10 }, 平滑 { stiffness: 100, damping: 20 }。
对于弹簧调优 (质量, 可视化器, 预设),加载 references/core-concepts-deep-dive.md。
集成指南
Vite: bun add motion → import { motion } from "motion/react" (开箱即用)
Next.js App Router: 需要 "use client" 指令或客户端组件包装器
"use client"
import { motion } from "motion/react"
Tailwind: ⚠️ 移除 transition-* 类 (与Motion动画冲突)
Cloudflare Workers: 使用 framer-motion v12.23.24 代替 (Motion有Wrangler构建问题)
对于完整集成指南 (Next.js模式, SSR, 框架特定问题),加载 references/nextjs-integration.md。
性能优化
包大小: 使用LazyMotion (34 KB → 4.6 KB):
import { LazyMotion, domAnimation, m } from "motion/react"
<LazyMotion features={domAnimation}>
<m.div>只有4.6 KB!</m.div>
</LazyMotion>
大型列表: 使用虚拟化 (react-window, react-virtuoso) 用于50+动画项。
对于完整优化指南 (硬件加速, 内存分析, 生产基准),加载 references/performance-optimization.md。
可访问性
尊重 prefers-reduced-motion:
import { MotionConfig } from "motion/react"
<MotionConfig reducedMotion="user">
<App />
</MotionConfig>
键盘支持: 使用 whileFocus 用于键盘触发动画。
<motion.button whileFocus={{ scale: 1.1 }} tabIndex={0}>
键盘可访问
</motion.button>
对于完整可访问性指南 (ARIA模式, 屏幕阅读器, AnimatePresence 解决方法, 测试),加载 references/accessibility-guide.md。
常见模式
模态对话框 (AnimatePresence + 背景):
<AnimatePresence>
{isOpen && (
<motion.dialog exit={{ opacity: 0 }}>内容</motion.dialog>
)}
</AnimatePresence>
手风琴 (高度动画):
<motion.div animate={{ height: isOpen ? "auto" : 0 }}>
内容
</motion.div>
对于15+生产模式 (轮播, 标签, 滚动显示, 视差, 通知),加载 references/common-patterns.md。
已知问题与解决方案
问题1: AnimatePresence 退出不工作 (最常见)
症状: 组件立即消失,没有退出动画。
解决方案: AnimatePresence 必须保持挂载,包装条件 (而不是被包装):
// ❌ 错误
{isVisible && <AnimatePresence><motion.div>内容</motion.div></AnimatePresence>}
// ✅ 正确
<AnimatePresence>
{isVisible && <motion.div key="unique">内容</motion.div>}
</AnimatePresence>
问题2: Next.js “use client” 缺失
症状: 构建失败,显示 “motion is not defined” 或 SSR错误。
解决方案: 添加 "use client" 指令:
"use client"
import { motion } from "motion/react"
问题3: Tailwind 过渡冲突
症状: 动画卡顿或不工作。
解决方案: 移除 transition-* 类 (Motion覆盖CSS过渡):
// ❌ 错误: <motion.div className="transition-all" animate={{ x: 100 }} />
// ✅ 正确: <motion.div animate={{ x: 100 }} />
问题4: Cloudflare Workers 构建错误
症状: 使用 motion 包时,Wrangler构建失败。
解决方案: 使用 framer-motion v12.23.24 代替 (GitHub问题 #2918):
bun add framer-motion # 相同API,适用于Workers
问题5: 大型列表性能
症状: 50-100+动画项导致严重减速。
解决方案: 使用虚拟化 (react-window, react-virtuoso)。
对于5+额外问题 (layoutScroll, layoutRoot, AnimatePresence + layoutId),加载 references/nextjs-integration.md 或 references/core-concepts-deep-dive.md。
何时加载参考
Claude应根据用户需求加载这些参考:
加载 references/core-concepts-deep-dive.md 当:
- 用户询问变体编排 (staggerChildren, delayChildren, 动态变体)
- 用户需要高级布局动画 (layoutId 共享过渡, LayoutGroup)
- 用户想要滚动链接动画 (useScroll 偏移, useTransform 缓动, 视差层)
- 用户需要复杂拖放模式 (动量, 弹性, 事件处理程序, 约束)
- 用户询问弹簧物理调优 (质量参数, 可视化器, 自定义预设)
加载 references/performance-optimization.md 当:
- 用户想将包大小减少到4.6 KB以下 (useAnimate mini, LazyMotion 比较)
- 用户提到 “应用慢”, “卡顿动画”, “延迟”, 或 “性能问题”
- 用户有50+动画项在列表中 (需要虚拟化)
- 用户需要内存分析或生产基准
加载 references/nextjs-integration.md 当:
- 用户使用Next.js构建 (App Router 或 Pages Router)
- 用户遇到SSR错误, “use client” 错误, 或水合问题
- 用户询问路由过渡或页面导航动画
- 用户需要Next.js特定解决方法 (Reorder组件, AnimatePresence 软导航)
加载 references/accessibility-guide.md 当:
- 用户询问 “prefers-reduced-motion” 或可访问性合规
- 用户需要ARIA集成模式 (角色, 标签, 公告)
- 用户想要屏幕阅读器兼容性
- 用户提到可访问性审计或WCAG合规
- 用户询问AnimatePresence reducedMotion 解决方法 (已知问题 #1567)
加载 references/common-patterns.md 当:
- 用户询问特定UI模式 (模态, 手风琴, 轮播, 标签, 下拉, 吐司等)
- 用户需要复制粘贴代码示例用于生产
- 用户想看到15+真实世界动画模式
加载 references/motion-vs-auto-animate.md 当:
- 用户决定在Motion和AutoAnimate库之间选择
- 用户提到 “简单列表动画” 或 “包大小担忧”
- 用户问 “我应该使用哪个动画库?” 或 “Motion是否过度?”
- 用户需要功能比较或决策矩阵
模板
此技能包括5个生产就绪模板在 templates/ 目录:
- motion-vite-basic.tsx - 基本Vite + React + TypeScript设置带有常见动画
- motion-nextjs-client.tsx - Next.js App Router模式带有客户端组件包装器
- scroll-parallax.tsx - 滚动动画, 视差, 和视口触发器
- ui-components.tsx - 模态, 手风琴, 轮播, 标签带有共享下划线
- layout-transitions.tsx - FLIP布局动画和共享元素过渡
复制模板到您的项目并根据需要自定义。
参考
此技能包括4个全面参考指南:
- motion-vs-auto-animate.md - 决策指南: 何时使用Motion vs AutoAnimate
- performance-optimization.md - 包大小, LazyMotion, 虚拟化, 硬件加速
- nextjs-integration.md - App Router vs Pages Router, “use client”, 已知问题
- common-patterns.md - 前15模式带有完整代码示例
见 references/ 目录获取详细指南。
脚本
此技能包括2个自动化脚本:
- init-motion.sh - 一键设置带有框架检测 (Vite, Next.js, Cloudflare Workers)
- optimize-bundle.sh - 转换现有Motion代码到LazyMotion用于更小包
见 scripts/ 目录获取自动化工具。
官方文档
- 官方网站: https://motion.dev
- GitHub: https://github.com/motiondivision/motion (30,200+ 星)
- 示例: https://motion.dev/examples (300+ 示例)
相关技能: auto-animate (简单列表), tailwind-v4-shadcn (样式), nextjs (App Router), cloudflare-worker-base
Motion vs AutoAnimate: 加载 references/motion-vs-auto-animate.md 获取详细比较。
令牌效率指标
令牌节省: ~83% (30k → 5k 令牌) | 错误预防: 100% (29+ 错误) | 时间节省: ~85% (2-3 小时 → 20-30 分钟)
包版本 (验证于 2025-11-07)
| 包 | 版本 | 状态 |
|---|---|---|
| motion | 12.23.24 | ✅ 最新稳定 |
| framer-motion | 12.23.24 | ✅ Cloudflare替代方案 |
| react | 19.2.0 | ✅ 最新稳定 |
| vite | 6.0.0 | ✅ 最新稳定 |
贡献
发现问题或有建议?
- 打开问题: https://github.com/secondsky/claude-skills/issues
- 见模板和参考获取详细示例
生产测试: ✅ React 19 + Next.js 15 + Vite 6 + Tailwind v4
令牌节省: ~83%
错误预防: 100% (29+ 文档化错误预防)
包大小: 2.3 KB (mini) - 34 KB (完整), 可优化到4.6 KB 带有LazyMotion
可访问性: MotionConfig reducedMotion 支持
准备使用! 安装带有 ./scripts/install-skill.sh motion