用途
Motion Advanced 是一套面向 React / Next.js 的高级动效模式技能,用于构建复杂、可交互、基于物理的动画。它需要先完成 motion-foundations 的配置,并在 motion-patterns 不足以满足需求时使用。
主要能力
该技能可产出以下内容:
- 拖拽交互:可拖拽卡片、拖拽关闭面板(drag-to-dismiss sheet)、Reorder.Group 可排序列表
- 手势 Hook:滑动检测、长按、捏合轮廓
- 文本动画组件:逐词显现、逐字打字机、数字计数器
- SVG 动画:路径描边(path draw-on)、图标变形、描边进度环
- 自定义 Hook:useScrollReveal、useHoverScale、useNavigationDirection、useInViewOnce
- 基于 useAnimate 的命令式序列,支持中断安全的 async/await
- 加载组件:spinner、shimmer 骨架屏、脉冲点、进度条、按钮加载态
核心原则
- 对于直接操控,基于物理的动画(useSpring、springs.*)比基于时长的动画更自然。
- useMotionValue + useTransform 可在不触发重渲染的情况下计算派生值。
- useAnimate 序列是命令式的且中断安全——在动画进行中调用 animate() 会自动取消前一个动画。
- Motion values(useMotionValue、useSpring)对 SSR 安全,不会导致 hydration 错误。
使用规则
- 拖拽交互必须在触屏设备上测试,而不仅是鼠标。drag 属性在两者上都可用,但手感和阈值不同。
- 无限动画必须在 document.visibilityState === "hidden" 时暂停,后台标签页不得消耗 GPU/CPU。
- 滑动阈值必须显式定义,不能仅凭速度推断意图,需结合偏移量 + 速度检查。
- useAnimate 的 scope ref 必须挂载到已挂载的 DOM 元素上,在挂载前调用 animate() 会静默抛错。
- Motion values 不得在渲染时重新创建。在组件体内使用 useMotionValue(0) 是正确的,在渲染中 new MotionValue(0) 则不正确。
- 所有 token 值均从 motion-foundations 导入,不使用内联数字。
- 自定义 Hook 必须处理清理逻辑,每个 window.addEventListener 都需要在 useEffect 返回中对应 removeEventListener。
- SVG 变形要求路径命令数相等,命令结构不同的路径会直接跳变而非插值。
决策指引
选择合适的高级 API:
- 释放时带物理效果的拖拽:drag + dragTransition: springs.release
- 有序拖拽重排列表:Reorder.Group + Reorder.Item
- 按拖拽偏移关闭:drag="y" + onDragEnd 偏移检查
- 左右滑动:drag="x" + onDragEnd 偏移检查
- 长按:useLongPress Hook
- 随时间平滑的值:useSpring
- 从另一个值派生的值:useTransform
- 多步序列:useAnimate 配合 async/await
- 一次性命令式动画:从 motion 导入 animate()
- 逐词进入文本:对 inline-block span 使用 stagger
- SVG 描边:pathLength 0 → 1
- SVG 变形:d 属性补间(命令数相等)
- 环形进度:strokeDashoffset 补间
useSpring 与 spring transition 的选择:
- useSpring:用于光标跟随、指针追踪值;每帧连续更新;中断时物理从速度平滑接管。
- transition: springs.*:用于离散状态变化;由状态变化触发;中断时从当前值重新开始。
核心概念
useMotionValue + useTransform:无需重渲染的响应式计算。
useAnimate:返回 [scope, animate],scope ref 必须挂载到 DOM 元素。animate() 调用是中断安全的,进行中调用会取消前一次运行。
代码示例
技能提供了可拖拽卡片、拖拽关闭面板、可排序列表、滑动检测、长按 Hook、逐词显现、数字计数器、SVG 路径描边、描边进度环、useScrollReveal Hook、光标跟随、shimmer 骨架屏、按钮加载态、带可见性暂停的无限动画等完整代码示例,以及一个结合 useMotionValue、useTransform、useSafeMotion、AnimatePresence 和 motion-foundations token 的端到端示例(带 shimmer 内容、加载状态和减少动效支持的拖拽关闭面板)。
限制 / 非目标
该技能不覆盖:
- Token 与弹簧定义 → 参见 motion-foundations
- 标准 UI 模式(按钮、模态、stagger、页面过渡)→ 参见 motion-patterns