nextjs-framer-motion-animations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNext.js + Motion/Framer Motion
Next.js + Motion/Framer Motion
Mission
任务目标
Build small, purposeful, accessible animations in Next.js using Motion for React (the current package) or legacy , without breaking server/client boundaries, performance, or usability.
framer-motion使用Motion for React(当前包)或旧版在Next.js中构建小巧、实用且可访问的动画,同时不破坏服务器/客户端边界、性能或可用性。
framer-motionUse this skill for
适用场景
- First-render reveals and section entrances
- Hover, tap, and focus feedback on buttons, links, cards, tabs, and navigation
- Scroll-triggered reveals and modest scroll-linked effects
- Modals, drawers, dropdowns, accordions, tabs, and other enter/exit UI
- Layout and shared-element transitions with and
layoutlayoutId - Reorderable lists and light route-content transitions
- Debugging Motion behaviour in Next.js
- 首次渲染显示与区块入场动画
- 按钮、链接、卡片、标签页和导航上的悬停、点击与焦点反馈
- 滚动触发的显示效果与适度的滚动关联动画
- 模态框、抽屉、下拉菜单、折叠面板、标签页及其他进入/退出类UI的动画
- 基于和
layout的布局与共享元素过渡layoutId - 可重排列表与轻量路由内容过渡
- 调试Next.js中的Motion行为
Do not use this skill for
不适用场景
- GSAP-style timelines or cinematic sequences
- Canvas, WebGL, Three.js, or Lottie-led animation systems
- Heavy parallax or scroll-jacking storytelling
- Large creative-direction rewrites
- Pure CSS effects that do not justify client JavaScript, unless Motion is explicitly requested
- GSAP风格的时间线或电影级序列动画
- Canvas、WebGL、Three.js或Lottie主导的动画系统
- 复杂视差或滚动劫持式叙事
- 大型创意方向重写
- 无需客户端JavaScript的纯CSS效果(除非明确要求使用Motion)
Non-negotiables
不可违背原则
- Prefer the lightest Motion API that solves the task.
- Preserve repo consistency. Do not mix and
motionimports in the same diff unless the task is an explicit migration.framer-motion - Keep animated logic in the smallest possible Client Component boundary.
- Respect reduced motion globally with and locally with
MotionConfig reducedMotion="user"when behaviour must change.useReducedMotion() - Prefer reusable primitives, variants, and motion tokens over repeated inline animation objects.
- Do not add a global provider, root-layout Client Component, or route-wide animation system unless the request genuinely needs it.
- 优先选择能解决任务的最轻量Motion API。
- 保持代码库一致性。除非任务明确是迁移,否则不要在同一个代码变更中混合和
motion导入。framer-motion - 将动画逻辑限制在尽可能小的Client Component边界内。
- 通过全局尊重减少动画的设置,当行为必须改变时,使用
MotionConfig reducedMotion="user"进行本地处理。useReducedMotion() - 优先使用可复用的基础组件、变体和motion令牌,而非重复的内联动画对象。
- 除非请求确实需要,否则不要添加全局提供者、根布局Client Component或路由级动画系统。
Default workflow
默认工作流程
1) Audit the codebase first
1) 首先审核代码库
Inspect:
- Router type: ,
app/, or both.pages/ - Current package: ,
motion, or neither.framer-motion - Existing animation patterns and design-system components.
- Candidate transition boundaries: ,
app/layout.tsx,app/template.tsx, shared UI shells.pages/_app.tsx - Whether the change is local animation, mount/unmount animation, layout animation, shared-element animation, reorder, or scroll-linked animation.
If shell access is available, run:
bash
node scripts/audit-nextjs-motion.mjs --root /path/to/repo
node scripts/inspect-motion-target.mjs path/to/target-file.tsx --root /path/to/repo
node scripts/plan-motion-change.mjs --root /path/to/repo --target path/to/target-file.tsx --task "user request"For broad skill iteration or repo-health checks, also run:
bash
node scripts/check-motion-antipatterns.mjs --root /path/to/repo检查:
- 路由类型:、
app/或两者兼有。pages/ - 当前使用的包:、
motion或都未使用。framer-motion - 现有动画模式与设计系统组件。
- 候选过渡边界:、
app/layout.tsx、app/template.tsx、共享UI壳。pages/_app.tsx - 变更类型:本地动画、挂载/卸载动画、布局动画、共享元素动画、重排或滚动关联动画。
如果可以访问代码壳,运行:
bash
node scripts/audit-nextjs-motion.mjs --root /path/to/repo
node scripts/inspect-motion-target.mjs path/to/target-file.tsx --root /path/to/repo
node scripts/plan-motion-change.mjs --root /path/to/repo --target path/to/target-file.tsx --task "user request"对于广泛的技能迭代或代码库健康检查,还可运行:
bash
node scripts/check-motion-antipatterns.mjs --root /path/to/repo2) Choose a package strategy
2) 选择包策略
Default rules:
- New work or modernised motion layer: prefer the current package with imports from
motion.motion/react - Existing repo already on : stay consistent unless the task explicitly includes migration.
framer-motion - Passive App Router component with no hooks or client-only logic: can be appropriate, but it is an exception, not the default.
motion/react-client - Leaf animations with hooks, route state, presence, reorder, or interactivity: use a small Client Component boundary.
See and .
references/MIGRATION.mdreferences/DECISION_TREE.md默认规则:
- 新工作或现代化动画层:优先使用当前的包,从
motion导入。motion/react - 现有代码库已使用:保持一致,除非任务明确包含迁移。
framer-motion - 无钩子或仅客户端逻辑的被动App Router组件:可能适用,但这是例外情况,而非默认选择。
motion/react-client - 包含钩子、路由状态、存在性、重排或交互性的叶子动画:使用小型Client Component边界。
详见和。
references/MIGRATION.mdreferences/DECISION_TREE.md3) Choose the lightest correct API
3) 选择最轻量的正确API
Use this decision rule:
- Simple local animation:
motion.* - Bundle-sensitive shared shell: with
m.*LazyMotion - Repeated parent/child orchestration: variants plus
stagger - Mount/unmount or route exits:
AnimatePresence - Layout changes from React re-render:
layout - Shared-element transition:
layoutId - Sibling layout coordination or namespaced shared layout IDs:
LayoutGroup - Simple scroll reveal:
whileInView - Scroll-linked progress or parallax: plus motion values
useScroll - Imperative sequence or external trigger:
useAnimate - Design-system component wrapper: with ref forwarding
motion.create()
See and .
references/EXPERT_PLAYBOOK.mdreferences/DECISION_TREE.md遵循以下决策规则:
- 简单本地动画:
motion.* - 对包体积敏感的共享壳:搭配
m.*LazyMotion - 重复的父/子编排:变体+
stagger - 挂载/卸载或路由退出:
AnimatePresence - React重渲染导致的布局变化:
layout - 共享元素过渡:
layoutId - 兄弟布局协调或命名空间共享布局ID:
LayoutGroup - 简单滚动显示:
whileInView - 滚动关联进度或视差:+运动值
useScroll - 命令式序列或外部触发:
useAnimate - 设计系统组件包装器:+转发ref
motion.create()
详见和。
references/EXPERT_PLAYBOOK.mdreferences/DECISION_TREE.md4) Wire it correctly for the router
4) 针对路由正确配置
App Router
App Router
- Passive, hook-free animation in a server-friendly file: consider .
motion/react-client - Interactive or hook-driven UI: create a small Client Component leaf and keep data fetching server-side.
- Client wrapper around server-rendered children: useful for modal shells, drawers, and local visibility wrappers.
- Route enter/exit choreography: mount a persistent Client shell from a layout so stays mounted.
AnimatePresence - Segment replay on navigation: is useful when you want remount semantics at a specific segment boundary.
template.tsx
See .
references/APP_ROUTER.md- 服务器友好文件中的被动、无钩子动画:可考虑。
motion/react-client - 交互式或基于钩子的UI:创建小型Client Component叶子节点,将数据获取保留在服务器端。
- 服务器渲染子组件的客户端包装器:适用于模态框壳、抽屉和本地可见性包装器。
- 路由进入/退出编排:从布局中挂载持久化的Client壳,使保持挂载状态。
AnimatePresence - 导航时的片段重放:当需要在特定片段边界实现重新挂载语义时,很有用。
template.tsx
详见。
references/APP_ROUTER.mdPages Router
Pages Router
- Keep stable in
AnimatePresencefor route transitions.pages/_app.tsx - Key routed children by a stable value that changes when you actually want a transition. For dynamic routes, is usually safer than
router.asPath.router.route - Do not rewrite for a one-off local animation.
_app.tsx
See .
references/PAGES_ROUTER.md- 在中保持
pages/_app.tsx稳定,用于路由过渡。AnimatePresence - 使用稳定值为路由子组件设置key,仅当确实需要过渡时才改变该值。对于动态路由,通常比
router.asPath更安全。router.route - 不要为一次性本地动画重写。
_app.tsx
详见。
references/PAGES_ROUTER.md5) Apply the motion budget
5) 应用动画预算
Default ranges unless the user or design system says otherwise:
- Micro-interactions: 0.12s to 0.22s, scale no larger than 1.03, travel no more than 4px.
- Reveal / list entrance: 0.18s to 0.35s, travel 8px to 24px.
- Page / route transition: 0.22s to 0.45s, mostly opacity plus small Y translation.
- Layout animation: prefer Motion springs or ; do not fake these with large manual transforms.
layout
See and .
references/EXPERT_PLAYBOOK.mdreferences/PERFORMANCE.md除非用户或设计系统另有规定,否则默认范围:
- 微交互:0.12秒至0.22秒,缩放不超过1.03,移动距离不超过4px。
- 显示/列表入场:0.18秒至0.35秒,移动距离8px至24px。
- 页面/路由过渡:0.22秒至0.45秒,主要为透明度变化加小幅Y轴位移。
- 布局动画:优先使用Motion弹簧或;不要用大型手动变换模拟这些效果。
layout
详见和。
references/EXPERT_PLAYBOOK.mdreferences/PERFORMANCE.md6) Validate before finishing
6) 完成前验证
Always check:
- No server/client boundary mistakes
- Reduced motion works
- Focus is preserved for interactive UI
- No unnecessary layout shift or stretched content
- No duplicate or conflicting route wrappers
- Project still builds
Run repo checks when available:
bash
npm run lint
npm run buildFor repo audits or skill iteration, also run:
bash
node scripts/check-motion-antipatterns.mjs --root /path/to/repoUse before finalising. When improving the skill itself, use and .
references/CHECKLIST.mdreferences/EVALUATION.mdnode scripts/run-evaluation-pack.mjs务必检查:
- 无服务器/客户端边界错误
- 减少动画功能正常
- 交互式UI的焦点保持正常
- 无不必要的布局偏移或内容拉伸
- 无重复或冲突的路由包装器
- 项目仍可正常构建
运行代码库检查(如果可用):
bash
npm run lint
npm run build对于代码库审核或技能迭代,还可运行:
bash
node scripts/check-motion-antipatterns.mjs --root /path/to/repo完成前使用进行检查。当改进技能本身时,使用和。
references/CHECKLIST.mdreferences/EVALUATION.mdnode scripts/run-evaluation-pack.mjsImplementation rules
实现规则
- Prefer animating transform and opacity. Avoid animating ,
top, large filters, and large shadows on big surfaces.left - When possible, turn the existing root element into a Motion element instead of adding a new wrapper. Extra wrappers often break layout, refs, selectors, or spacing.
- If using plus
m, use:LazyMotion- for standard animations, variants, exit, hover, tap, and focus.
domAnimation - only when you need layout animations or drag/pan.
domMax
- Use for app-level wrappers unless first-load animation is explicitly desired.
AnimatePresence initial={false} - Use only when a single child should fully exit before the next enters.
AnimatePresence mode="wait" - Never key exit-sensitive children by array index.
- Start with before manual height choreography. If content stretches, add
layoutto the affected children or switch tolayoutfor aspect-ratio changes.layout="position" - If the scroll container is not the window, configure or use
viewport.rootwith the correct root.useInView - When animating or image wrappers, preserve the layout box and animate transform or opacity rather than intrinsic size.
next/image - When wrapping design-system components, call outside render and make sure the wrapped component forwards its ref.
motion.create() - If the user did not explicitly ask for Motion and the effect is just a tiny hover or focus style on a static server-rendered element, CSS may be the cleaner answer.
- 优先为transform和opacity添加动画。避免为、
top、大型滤镜和大表面上的大型阴影添加动画。left - 尽可能将现有根元素转换为Motion元素,而非添加新的包装器。额外的包装器通常会破坏布局、ref、选择器或间距。
- 如果使用搭配
m,请使用:LazyMotion- 用于标准动画、变体、退出、悬停、点击和焦点效果。
domAnimation - 仅当需要布局动画或拖拽/平移时才使用。
domMax
- 应用级包装器使用,除非明确需要首屏加载动画。
AnimatePresence initial={false} - 仅当单个子组件完全退出后下一个才应进入时,使用。
AnimatePresence mode="wait" - 切勿使用数组索引为对退出敏感的子组件设置key。
- 在手动处理高度编排之前先尝试。如果内容拉伸,为受影响的子组件添加
layout,或针对宽高比变化切换为layout。layout="position" - 如果滚动容器不是窗口,配置或使用带有正确根元素的
viewport.root。useInView - 为或图片包装器添加动画时,保留布局框,为transform或opacity添加动画而非内在尺寸。
next/image - 包装设计系统组件时,在渲染外部调用,并确保包装后的组件转发其ref。
motion.create() - 如果用户未明确要求使用Motion,且效果只是静态服务器渲染元素上的微小悬停或焦点样式,CSS可能是更简洁的解决方案。
Scripts
脚本
- - inspects a repo, ranks likely target files, and emits JSON recommendations.
scripts/audit-nextjs-motion.mjs - - inspects one file and recommends boundary, import path, risks, and likely pattern fit.
scripts/inspect-motion-target.mjs - - combines repo audit, target inspection, and task wording into a structured expert plan.
scripts/plan-motion-change.mjs - - scans a repo for common Motion and Framer Motion anti-patterns and emits JSON findings.
scripts/check-motion-antipatterns.mjs - - runs the bundled fixture-and-golden evaluation pack for skill iteration.
scripts/run-evaluation-pack.mjs - - copies template components from
scripts/scaffold-motion-primitives.mjsinto a target directory, with optional import rewriting for legacyassets/.framer-motion
- - 检查代码库,对可能的目标文件排序,并输出JSON建议。
scripts/audit-nextjs-motion.mjs - - 检查单个文件,建议边界、导入路径、风险和可能的模式适配。
scripts/inspect-motion-target.mjs - - 结合代码库审核、目标文件检查和任务描述,生成结构化的专家方案。
scripts/plan-motion-change.mjs - - 扫描代码库中常见的Motion和Framer Motion反模式,并输出JSON结果。
scripts/check-motion-antipatterns.mjs - - 运行捆绑的测试用例与标准输出评估包,用于技能迭代。
scripts/run-evaluation-pack.mjs - - 将
scripts/scaffold-motion-primitives.mjs中的模板组件复制到目标目录,可选择为旧版assets/重写导入路径。framer-motion
Reference map
参考文档映射
- - API selection, heuristics, motion tokens, anti-patterns
references/EXPERT_PLAYBOOK.md - - fast pattern and boundary selection
references/DECISION_TREE.md - - App Router boundaries, route shells,
references/APP_ROUTER.md, and server-friendly patternstemplate.tsx - -
references/PAGES_ROUTER.md, keys, dynamic route nuances_app.tsx - - copy/paste implementations
references/RECIPES.md - - bundle size, LazyMotion, layout and scroll performance
references/PERFORMANCE.md - - reduced motion, focus, modal guidance
references/ACCESSIBILITY.md - -
references/MIGRATION.mdtoframer-motionpackage strategymotion - - failure modes and fixes
references/TROUBLESHOOTING.md - - final review before finishing
references/CHECKLIST.md - - trigger tests, scenario fixtures, anti-pattern scans, and golden-output review
references/EVALUATION.md
- - API选择、启发式方法、motion令牌、反模式
references/EXPERT_PLAYBOOK.md - - 快速选择模式与边界
references/DECISION_TREE.md - - App Router边界、路由壳、
references/APP_ROUTER.md和服务器友好模式template.tsx - -
references/PAGES_ROUTER.md、key、动态路由细节_app.tsx - - 可复制粘贴的实现方案
references/RECIPES.md - - 包体积、LazyMotion、布局与滚动性能
references/PERFORMANCE.md - - 减少动画、焦点、模态框指南
references/ACCESSIBILITY.md - -
references/MIGRATION.md到framer-motion包的迁移策略motion - - 故障模式与修复方案
references/TROUBLESHOOTING.md - - 完成前的最终检查清单
references/CHECKLIST.md - - 触发测试、场景测试用例、反模式扫描和标准输出审查
references/EVALUATION.md
Output expectations
输出预期
When modifying a repo, finish with:
- The files changed
- The Motion API and pattern chosen
- Boundary strategy and package migration decision, if any
- Reduced-motion handling
- Performance or bundle-size choices, if relevant
- Manual validation notes or commands run
- Any caveats the developer should know
修改代码库后,需包含以下内容:
- 变更的文件
- 选择的Motion API与模式
- 边界策略与包迁移决策(如有)
- 减少动画的处理方式
- 性能或包体积相关选择(如有)
- 手动验证说明或运行的命令
- 开发者应了解的注意事项
Typical request mapping
典型请求映射
- "Make this button feel better" -> micro-interaction recipe
- "Animate cards in on scroll" -> reveal recipe; variants if staggered
- "Add a smooth route transition in App Router" -> persistent layout-mounted shell or content wrapper, not a root rewrite by default
- "Animate this accordion or tab underline" -> /
layout/layoutIdLayoutGroup - "Make this drag list reorder smoothly" -> /
Reorder.GroupReorder.Item - "This breaks in App Router" -> inspect boundary and import path before editing
- "Modernise our Framer Motion setup" -> audit first, then use
references/MIGRATION.md
- "让这个按钮体验更好" -> 微交互方案
- "滚动时让卡片入场动画" -> 显示方案;如需 stagger 效果则使用变体
- "在App Router中添加平滑路由过渡" -> 持久化布局挂载壳或内容包装器,默认不重写根组件
- "为这个折叠面板或标签页下划线添加动画" -> /
layout/layoutIdLayoutGroup - "让这个拖拽列表平滑重排" -> /
Reorder.GroupReorder.Item - "这在App Router中失效了" -> 编辑前先检查边界与导入路径
- "现代化我们的Framer Motion配置" -> 先审核,再使用
references/MIGRATION.md