mcpField
A
animate

animate

github.com/aladicf设计与 UI562 次安装8 周前更新
代码仓库

关于 animate

用于规划和实现有明确目的的界面动效的设计技能,帮助设计师和开发者改善反馈与引导,并兼顾性能、输入方式和减少动效需求。

主要功能

  1. 01动效评估与规划
  2. 02时长、缓动和编排指引
  3. 03减少动效的替代方案
  4. 04手势与过渡模式
  5. 05兼顾性能的实现选择

适用场景

  1. 01为按钮和表单提交添加反馈
  2. 02平滑页面及状态切换
  3. 03设计抽屉、手势或错峰动画
  4. 04根据减少动效偏好调整动画

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aladicf/better-react-web-ui --skill animate

安装后在 Claude Code 中输入/animate确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
animation-purpose.md
asymmetric-press-release.md
attribution-and-sources.md
avoid-css-variables-drag.md
blur-bridge-states.md
button-press-scale-097.md
clip-path-layout-free-reveals.md
clip-path-tab-transitions.md
custom-easing-curves.md
damp-drag-boundaries.md
drawer-500ms-duration.md
ease-in-out-on-screen-movement.md
ease-out-default.md
easing-context.md
entrance-animations.md
exit-animations.md
faster-improves-performance.md
gesture-interactions.md
hardware-accelerated-busy-main-thread.md
hover-gap-fill.md
immediate-feedback-actions.md
interaction-frequency.md
interruptible-animations.md
marketing-exception.md
micro-interactions.md
momentum-dismissal.md
never-scale-zero.md
no-animation-for-keyboard.md
opacity-reduced-motion-fallback.md
origin-aware-animations.md

详细介绍

分析功能,并添加动效,以提升界面的清晰度、反馈效果、感知性能和精致感,同时避免让界面显得迟缓、嘈杂或浮夸。

必须完成的准备工作

阅读 frontend-design,并遵循其中的上下文收集流程。复用已有上下文,仅针对会产生重大影响的信息缺口提问。此外,还要了解:性能约束。 有关时长、缓动、编排和减少动态效果的处理,请参阅 motion reference。 如果需要按使用场景浏览更深入的动态效果库,而不是猜测文件名,请参阅 animate reference index。 如果动态效果需要强化凸起、按压、内嵌、拖动或分层的深度感,请参阅 elevation system。 如果动画决策涉及焦点、加载、过渡或反馈状态,请参阅 interaction reference。 如果动态效果会影响按钮、标签页、工具提示、轻提示、切换开关、抽屉或提交操作等自定义基础组件,请参阅 component anatomy reference。 如果动态效果需要适配紧凑视口、粗略指针场景或较小的视口空间,请参阅 responsive design reference。 在做出框架特定的动画决策之前,请参阅 framework official docs reference。 如果需求涉及 React 轻提示、抽屉、文本动态效果或其他已有强大加速器支持的 UI 模式,请参阅 React shadcn accelerators reference。 若要判断何时可以使用 Tailwind 工具类、兼容 Tailwind 的关键帧或 WAAPI 来简洁实现动态效果,而无需使用框架动画库,请参阅 Tailwind and WAAPI motion reference。 如果要定义 CSS linear() 缓动令牌、Tailwind 动态效果令牌、React 组件动态效果示例或 View Transition 缓动,请参阅 linear easing patterns reference。 如果需要编排多元素动态效果、交错显现、列表插入/移除/重排、模态框堆叠、抽屉序列、路由编排或密集交互流程,请参阅 motion choreography reference。 如果动态效果应随滚动位置而非时间推进,请参阅 scroll-driven animations reference。 如果要通过共享元素连续性为页面状态或 DOM 变化添加动画,请参阅 view transitions reference。 有关此技能中 Emil 风格动态效果指导的来源脉络,请参阅 attribution and sources。 按动态效果类型整理的指南请参阅 entrance animations、exit animations、gesture interactions 和 micro-interactions。 选择动态效果曲线时,请参阅 ease-out defaults、easing by context 和 custom easing curves。 如果主要问题是时长而非缓动,请参阅 UI under 300ms、asymmetric press and release timing、500ms drawer timing、faster perceived performance 和 tooltip timing escalation。 如果动态效果模式需要更具体的指导,请参阅 on-screen movement easing、sheet and drawer easing 和 spring motion。 实现手势密集型界面时,请参阅 damped drag boundaries、upward drag friction、interruptible animations、momentum dismissal、pointer capture、scroll and drag conflicts 和 velocity-aware snap points。 有关完善效果与无障碍体验,请参阅 blur-bridged transitions、clip-path tabs、respect reduced motion、opacity fallback、reduced motion alternatives、Motion 的 useReducedMotion、hover gap fill、scroll reveal thresholds、child orchestration 和 toast stack depth。 如果需要为性能敏感场景选择属性,请参阅 transform and opacity only、avoid inherited token mutation in drag loops、clip-path reveals、hardware-accelerated motion under load 和 surgical will-change。 对于侧重策略的动态效果决策,请参阅 immediate action feedback、interaction frequency、no keyboard animation、marketing exceptions 和 animation purpose。 如果问题实际关乎变换技术和空间感,请参阅 preserve-3d effects、never scale from zero、origin-aware animations 和 percentage translateY。 有关更精细的变换效果细节,请参阅 button press scale 0.97、scale affecting children 和 SVG path morph disclosure icons。 如果界面在频繁使用时已经显得迟缓,也加载 optimize。 如果界面需要更好地应对减少动态效果、错误、溢出、边缘情况或混合输入模式,也加载 harden。


致谢与灵感来源

本技能的动态效果指南部分参考了 Emil Kowalski 的 animations.dev 课程,尤其强调缓动选择、时长、恰到好处的克制、弹簧效果,以及让生产环境中的 UI“感觉恰到好处”的动态效果。

本指南也参考了 Emil 在 Sonner 和 Vaul 上的开源作品,这些作品以动画见长,并且与本库中关于 React 提示框和抽屉的指南相关。

本仓库将这些经验改写为原创且针对本仓库的指南,而非直接复现课程材料。


动态效果的应用原则

添加任何动画前,请按以下顺序判断:

  1. 先修正结构 — 动态效果应强化层级和状态,而不是挽救令人困惑的布局。
  2. 动画必须有明确作用 — 每个动画都应改善反馈、方向感、关联性或趣味性。
  3. 优先考虑速度 — 产品 UI 首先应让人感觉响应迅速,其次才是令人印象深刻。
  4. 让动态效果可中断 — 新的用户意图应优先于完成旧动画。
  5. 匹配输入方式 — 精确指针、粗略指针和键盘交互不应一概采用相同的动态效果处理方式。
  6. 提前规划减少动态效果的方案 — 无障碍性是系统的一部分,不是事后补救。
  7. 优先采用满足需求的最轻量实现 — 首选 Tailwind 工具类和兼容 Tailwind 的关键帧;需要命令式控制时长时使用 WAAPI;只有交互确实需要时才使用 Motion。

动态效果应至少用于以下一项:

  • 反馈 — 确认某项操作已发生
  • 方向感 — 帮助用户了解某项内容从何处出现或去了哪里
  • 关联性 — 展示界面、层级和控件在空间上的关系
  • 趣味性 — 在基础体验已完善后增添温度或个性
  • 层级:明确哪些变化最大,以及原因
  • 焦点引导:将注意力引向正确目标,同时不夺取控制权

如果动画无法证明自己能发挥上述作用之一,就将其删掉。

评估动态效果的应用机会

分析哪些地方可以通过动态效果改善体验:

  1. 找出静态区域:

    • 缺少反馈:操作后没有视觉确认(例如点击按钮、提交表单等)
    • 突兀的过渡:状态瞬间变化,显得生硬(显示/隐藏、页面加载、路由切换)
    • 关系不清晰:空间或层级关系不够明显
    • 缺少趣味性:交互虽实用,却枯燥乏味
    • 错过引导机会:可以引导注意力或说明行为的场景
  2. 了解使用情境:

    • 产品的个性是什么?(活泼还是严肃,充满活力还是平和)
  • 性能预算是多少?(优先紧凑布局?复杂页面?)
  • 目标用户是谁?(对动态效果敏感的用户?追求速度的高级用户?)
  • 什么最重要?(一个重点动画还是许多微交互?)
  • 哪些输入方式很重要?(精确指针、粗略指针、键盘、触控笔)
    • 哪些交互发生频率较高,因此尤其需要保持灵敏?

如果无法从代码库中判断上述任何一点,请直接向用户询问无法推断的信息。

关键:遵循 prefers-reduced-motion。始终为有需要的用户提供不含动画的替代方案。

动态效果应强化层级,而不是弥补层级设计薄弱的问题。如果只有加入动态效果后布局才变得易于理解,就应先修正布局。

制定动画策略

制定有目的的动画计划:

  • 核心时刻:哪一个动画是标志性动画?(页面加载?主视觉区域?关键交互?)
  • 反馈层:哪些交互需要确认反馈?
  • 过渡层:哪些状态变化需要平滑处理?
  • 手势层:哪些拖动、滑动、吸附或关闭交互需要符合物理规律?
  • 惊喜层:哪里可以带来惊喜和愉悦?
  • 深度逻辑:哪些元素应呈现凸起、按压、拖动、凹陷或分层的效果?
  • 减少动态效果计划:哪些效果应简化为淡入淡出、模糊或即时状态变化?
  • 性能预算:哪些动画因频繁触发而必须保持轻量?

重要:精心编排的一体化体验,胜过四处分散的动画。聚焦于影响力最大的时刻。

默认动态效果规则

除非产品情境有充分理由偏离,否则动画工作应遵循以下默认指南。

1. 策略与目的
  • 每个动画都必须通过反馈、定位、关系或愉悦感证明其存在的价值。
  • 产品界面通常应给人快速、平静、精准的感觉。较慢或更具戏剧性的动画应留给新手引导、核心时刻、叙事或营销页面。
  • 优先采用一个标志性时刻加上克制的微交互,而不是到处添加动画。
  • 不要仅仅因为指针交互会播放动画,就给键盘触发的操作添加动画。键盘用户通常希望状态可预测地变化,且延迟尽可能短。
  • 交互发生得越频繁,通常越不需要动画。高频控件应几乎即时响应。
  • 立即确认用户输入。微交互应尽可能在约 80ms 内提供可见反馈。
  • 如果实际操作可能超过约 400ms,应立即通过乐观 UI、骨架屏、进度提示或明确的加载反馈进行响应,不要让界面毫无反应。
  • 切勿用动画掩盖加载缓慢、层级薄弱或状态设计缺失的问题。
2. 缓动默认值
  • 进入、显现和大多数反馈过渡,默认使用缓出。
  • 使用 Tailwind 任意缓动值或主题令牌定义的自定义三次贝塞尔曲线,而不是通用的 ease 默认值。
  • 对可逆且在屏幕上往返变化的状态,使用缓入缓出。
  • 当移动应与手势输入或物体行为形成物理关联时,使用弹簧动画。
  • 对抽屉、面板及类似表面,一个不错的起始选择是面板风格曲线 cubic-bezier(0.32, 0.72, 0, 1)。
  • 精致的 UI 动效优先采用指数风格的减速曲线,例如 ease-out-quart、ease-out-quint 或 ease-out-expo。
  • 除非产品有意采用玩具般或俏皮的物理隐喻,否则应避免弹跳和弹性曲线。它们通常显得过时、嘈杂或刻意。
  • 根据情境匹配缓动方式:
    • 表面进入 → 缓出
    • 表面退出 → 时长更短,通常使用缓入或更利落的退出曲线
    • 状态切换/可逆移动 → 缓入缓出
    • 与手势关联的移动 → 弹簧动画或基于速度的插值
    • 持续的自主动画 → 线性,除非循环需要刻意营造机械感
3. 时长与持续时间
  • 大多数重复出现的 UI 动效应控制在 300ms 以内。
  • 按压状态、开关、颜色变化和即时反馈等微交互,使用 100-150ms。
  • 工具提示、下拉菜单、菜单、悬停状态和小范围显现等标准 UI 动效,使用 150-250ms。
  • 对话框、抽屉和中等程度的界面过渡,如果不需要类似底部面板的厚重感,使用 200-300ms。
  • 手风琴、面板、抽屉和主要界面变化等较大的布局过渡,使用 300-500ms。
  • 将 500ms 视为面板或分阶段入场等较大界面动效的特殊上限,而非普通控件的默认时长。
  • 退出动画应比入场动画更快。一个不错的默认值是入场时长的 75% 左右。
  • 按下动作应比松开更快。向下反馈应当即时;复位则可以稍微柔和一些。
  • 首次出现工具提示或悬停显示的辅助信息时,必要时可以添加延迟;但后续相关信息的显示应快得多,甚至即时显示,以免界面显得迟钝。
  • 对于小型分组入场,建议从 30-80ms 的间隔开始。过长的交错链会显得不自然。限制交错总时长,避免最后一项姗姗来迟。
  • 根据移动距离和视觉体量匹配时长。元素越大、移动距离越长,通常需要比小范围变化稍多一点时间。
4. 属性选择与性能
  • 优先对 transform 和 opacity 设置动画。
  • 避免在生产环境 UI 中使用 transition-all。应指定需要变化的属性,例如 transition-[transform,opacity]、transition-transform、transition-opacity 或 transition-colors。
  • 除非有充分理由且界面较小,否则避免为 width、height、top、left、padding、margin、border-width 或其他对布局影响较大的属性设置动画。
  • 对于类似手风琴的高度过渡,尽可能使用 grid-template-rows 或其他对布局更友好的模式,而不是直接为 height 设置动画。
  • 需要不影响布局的显现效果时,使用 clip-path、蒙版或合成显现效果。
  • 主线程繁忙或组件动画频繁时,使用对硬件友好的完整变换,例如 translateX(...)、translateY(...) 或 translate3d(...)。避免在负载较高时使用会修改布局位置值的框架属性;如果真实的变换就能实现效果,应优先使用变换。
  • 谨慎使用 will-change,仅在动画即将发生或已证实确有需要时使用。
  • 在拖动循环中,避免使用会让每一帧都经过开销较大的继承令牌或布局重新计算流程的动画设置,以免引入延迟。
  • 对滚动触发的动效,优先使用 Intersection Observer;如果动效只需发生一次,应在完成后停止观察。
5. 变换与缩放技巧
  • 对按钮或标签的按压反馈,scale(0.97) 是一个很好的默认起点。
  • 入场动画绝不要从 scale(0) 开始。从接近 scale(0.95) 或更高的值开始,才能让元素保有可信的体量感。
  • 如果移动距离应随元素或视口尺寸变化,使用基于百分比的平移值。
  • 动效应考虑变换原点:
    • 菜单和工具提示应从触发边缘显现
    • 抽屉和面板应从其锚定的一侧移入
    • 卡片抬起时,应让人感觉它从所在平面升起
  • 请记住,缩放会影响子元素。如果缩放幅度过大,文字和图标可能会显得模糊或变形。
  • 仅当 3D 变换能提升空间感或带来显著的趣味性时才使用。不要只因为 preserve-3d 单独看起来很炫就使用它。
6. 手势与交互模式
  • 让交互动画可中断。用户不应为了表达新的意图而等待动画结束。
  • 对于快速触发的悬停、按压、菜单和弹出框状态,优先使用 CSS 过渡而非关键帧,因为用户意图改变时,过渡可以平滑反向。
  • 对于原生对话框和弹出框,可以考虑使用 @starting-style 和 transition-behavior: allow-discrete 实现 display/顶层的进入和退出效果,但要确保渐进增强,绝不能用动画技巧替代对焦点或生命周期的正确处理。
  • 对于滑动关闭、面板吸附等类似手势,应结合距离和速度,而不只是距离。
  • 在边界附近添加摩擦或阻尼,让拖动产生阻力,而不是突然停下。
  • 有意处理滚动与拖动的冲突。嵌套表面不应让用户感觉输入操作彼此争夺。
  • 实现拖动交互时,使用指针捕获等可靠的指针处理方式,或采用等效的手势控制机制。
  • 通过阴影、轻微缩放或提升图层等深度效果,让被拖动的项目在视觉上浮起。
  • 如果表面可被拖过静止位置,应允许受控的阻力,而不是让手势感觉突然受阻。
  • 吸附点应考虑速度并经过精心设计,不能像任意的隐形墙。
7. 无障碍与润色
  • 始终遵循 prefers-reduced-motion。
  • 减少动态效果通常应意味着简化动态效果,而不是完全不给反馈。尽可能用不透明度、模糊、高亮或更短的过渡替代大幅度的空间移动。
  • 保留焦点状态、进度、加载反馈以及成功或错误确认等功能性提示。
  • 当直接切换显得生硬时,可谨慎使用模糊效果来衔接视觉状态。
  • 有目的地使用错开动画来编排效果,而不是单纯装饰。小型列表可能适用,大型列表通常不适用。
  • 仅在支持悬停且具备指针能力时启用仅限悬停的动态效果。在 Tailwind 中,如果触控时悬停动态效果可能误触发,优先使用 motion-safe: 加自定义 @media (hover: hover) and (pointer: fine) 变体,或使用 CSS。
  • 滚动显现效果应在用户完全滚过元素之前触发,但也不能过早,以免效果脱离滚动上下文。
  • 在触发区域与浮动表面之间填补悬停空隙,避免指针移动时工具提示、菜单和弹出框闪烁关闭。
  • Toast 堆叠可通过偏移、缩放和不透明度营造层次感,同时避免显得混乱。
  • 在紧凑布局和粗指针环境中,也要像在宽屏布局中一样考虑用户对动态效果的敏感度。过度使用手势驱动的移动效果尤其容易令人不适。

实现动画

系统地为以下类别添加动态效果:

进入动画
  • 页面加载编排:仅在有助于理解时使用错开效果;整体编排应简洁
  • 主视觉区域:如果符合产品调性,为核心叙事场景设计独特的进入效果
  • 内容显现:使用交叉观察器触发滚动动画
  • 模态框/抽屉进入:平滑滑入并淡入、背景渐显,同时管理焦点
微交互
  • 按钮反馈:
    • 悬停:仅在有助于明确可供操作性时,使用轻微缩放、颜色变化或阴影变化
    • 点击/按压:快速缩小后恢复、呈现按下的感觉,或改变深度
    • 加载:显示旋转指示器或脉动状态
  • 表单交互:
    • 输入框聚焦:通过边框、背景或高度变化明确焦点,同时避免分散注意力
    • 验证:优先通过清晰的颜色、图标或文本状态变化来提示,再考虑装饰性动画
  • 切换开关:平滑滑动并过渡颜色
  • 复选框/单选按钮:快速呈现清晰的状态变化
  • 点赞/收藏:仅在符合产品调性时,使用轻微缩放或图标动画
状态转换
  • 显示/隐藏:淡入淡出并滑动(而非瞬间切换),时长适当(200-300ms)
  • 展开/折叠:采用便于布局的打开/关闭过渡,并处理溢出;必要时旋转图标
  • 加载状态:骨架屏淡入淡出、加载指示器动画、进度条
  • 成功/错误:颜色过渡、图标动画、轻柔的缩放脉冲
  • 启用/禁用:透明度过渡、光标变化
导航与流程
  • 页面过渡:在路由间交叉淡化;仅在确实有助于理解连续性时使用共享元素过渡
  • 标签页切换:滑动指示器、内容淡入淡出、clip-path 或其他快速的方向性提示
  • 轮播/滑块:平滑变换、吸附点、惯性,以及可中断的输入
  • 滚动效果:视差图层、状态变化的粘性页眉、滚动进度指示器
反馈与引导
  • 悬停提示:工具提示淡入、光标变化、元素高亮
  • 拖放:抬升效果(阴影 + 缩放)、放置区域高亮、平滑重新定位——拖动时,项目应像沿 z 轴向前弹出一样
  • 复制/粘贴:粘贴时短暂闪烁高亮,并显示“已复制”确认提示
  • 焦点流:高亮显示表单或工作流中的路径
深度与抬升动效
  • 抬升的元素应给人向用户靠近的感觉
  • 按下的元素应给人向内或向下移动的感觉
  • 结合阴影与位移来传达状态,而不只是装饰
  • 动效强调应与颜色和排版所采用的层级逻辑一致
惊喜时刻
  • 空状态:插图采用微妙的浮动动画
  • 完成操作:彩纸、勾号特效、成功庆祝效果
  • 隐藏彩蛋:等待用户发现的隐藏交互
  • 情境动画:天气效果、时段主题、季节性点缀

技术实现

针对不同动画选择合适的技术:

机制选择

选择能够满足交互需求的最轻量机制:

  • Tailwind transition 工具类:用于可逆的单元素状态变化,例如悬停、选中、按下、打开或关闭
  • 兼容 Tailwind 的关键帧:用于重复或多阶段时间线,例如加载动画、注意力脉冲、分阶段显示或编排动效
  • WAAPI:用于命令式排序、播放控制、取消/反转行为,或与逻辑同步动画
  • View Transitions API:用于 DOM 切换时保持连贯性、路由过渡、列表/详情过渡或布局模式变化

除非工具类、Tailwind 关键帧、WAAPI 或 View Transitions 确实无法胜任,否则不要升级使用动画框架库。

时长与缓动

按用途设置时长:

  • 100-150ms:即时反馈(按钮按下、切换)
  • 200-300ms:状态变化(悬停、菜单打开)
  • 300-500ms:布局变化(折叠面板、模态框、抽屉)
  • 默认最长 500ms:确实需要较长时长的大面积过渡

缓动曲线(通过 Tailwind 任意值或主题令牌使用):

/* Recommended - natural deceleration */
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);    /* Smooth, refined */
--ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);   /* Slightly snappier */
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);     /* Confident, decisive */
--ease-in-out-standard: cubic-bezier(0.65, 0, 0.35, 1); /* Reversible movement */
--ease-sheet-standard: cubic-bezier(0.32, 0.72, 0, 1);   /* Sheets / drawers */

/* AVOID - feel dated and tacky */
/* bounce: cubic-bezier(0.34, 1.56, 0.64, 1); */
/* elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6); */

**退出动画应比进入动画更快。**使用进入动画时长的约 75%。

兼容 Tailwind 的动画
/* Prefer for simple, declarative animations through Tailwind utilities or keyframes */
- transitions for state changes
- @keyframes for complex sequences
- transform + opacity first (GPU-friendly)
- Tailwind utilities when the project already uses Tailwind

Tailwind 示例:

<button className="transition-transform duration-150 ease-[cubic-bezier(0.16,1,0.3,1)] active:scale-[0.97] motion-reduce:transition-none motion-reduce:transform-none">
  Save
</button>

<div className="transition-[transform,opacity] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] data-[state=open]:scale-100 data-[state=open]:opacity-100 data-[state=closed]:scale-95 data-[state=closed]:opacity-0 origin-[var(--radix-popover-content-transform-origin)]">
  ...
</div>

当不同状态分别控制不同的变换通道时,使用各自独立的 Tailwind 变换工具类:

<div className="translate-y-2 scale-95 opacity-0 transition-[translate,scale,opacity] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] data-[state=open]:translate-y-0 data-[state=open]:scale-100 data-[state=open]:opacity-100 motion-reduce:translate-y-0 motion-reduce:scale-100">
  ...
</div>

仅当变换顺序需要有意耦合时,才使用任意变换简写。不要把 translate3d() 当作通用性能技巧;应先进行性能分析,或仅将其用于实际的 3D/透视效果。

兼容 Tailwind 的 linear() 缓动令牌适用于分段速度控制、柔和进入、利落退出和可控的缓动到位。优先使用命名主题令牌,而不是一次性的任意值:

@theme {
  --ease-enter-soft: linear(0, 0.08 12%, 0.34 36%, 0.74 66%, 0.93 84%, 1);
  --ease-exit-crisp: linear(0, 0.3 18%, 0.72 58%, 0.9 78%, 1);
  --ease-settle-gentle: linear(0, 0.06 10%, 0.31 32%, 0.72 62%, 0.92 82%, 1);
  --ease-emphasis-pop: linear(0, 0.38 20%, 0.88 62%, 1);
}
JavaScript 动画
/* Use for complex, interactive animations */
- Web Animations API for programmatic control
- Framer Motion / Motion for React
- GSAP for complex sequences

默认规则:如果悬停、按下、显示或减少动态效果的回退方案可以用 Tailwind 工具类或兼容 Tailwind 的关键帧清晰实现,那么在升级到 Motion 之前应优先采用这些方式。

性能
  • GPU 加速:使用 transform 和 opacity,避免使用布局属性
  • will-change:仅在已知动画开销较大时谨慎添加
  • 减少绘制:尽量减少重绘,并在适当情况下使用 contain
  • 监控 FPS:确保目标设备达到 60fps
  • 交互优先:即使在性能较弱的设备上,频繁的产品交互也应保持响应灵敏
无障碍
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

优先用短暂淡入、突出显示、模糊过渡或即时状态变化来替代大幅度移动,而不是删除所有形式的反馈。

实用的默认值

将以下数值作为起点,再根据具体情况调整:

值适用的默认场景
scale(0.97)按钮和标签的按压反馈
scale(0.95)最小且可信的进入缩放比例
200ms标准 UI 过渡
300ms常见 UI 动效的柔性上限
500ms大型面板/抽屉过渡的上限
cubic-bezier(0.32, 0.72, 0, 1)抽屉/底部面板的缓动
10-16pxToast 堆叠偏移的起始范围
~100px from viewport edge滚动显现触发位置的起始值

切勿:

  • 默认使用弹跳或弹性缓动曲线——这会让动画本身喧宾夺主
  • 在 transform 或 opacity 可以实现效果时,仍对 width、height、top 或 left 等布局属性做动画
  • 为常规反馈使用过长的持续时间——很快就会让人觉得迟钝
  • 做没有明确目的的动画——每个动画都必须有理由
  • 忽略 prefers-reduced-motion——这是无障碍违规行为
  • 为所有内容添加动画——动画疲劳会让界面令人不堪其扰
  • 强迫用户等到动画结束才能继续操作
  • 用动效掩盖结构薄弱、层级不清或数据获取缓慢的问题
  • 发布忽略惯性、阻尼或滚动冲突的手势逻辑

验证质量

全面测试动画:

  • 保持 60fps 流畅运行:目标设备上不卡顿
  • 感觉自然:缓动曲线自然流畅,而非机械生硬
  • 时机恰当:不过快(令人突兀),也不过慢(令人迟钝)
  • 即时响应:输入操作能迅速得到可见反馈
  • 必要时可中断:新的意图可以覆盖旧动画
  • 手势体验良好:拖动、滑动、吸附和关闭交互符合物理直觉
  • 支持减少动效:动画会根据需要停用或简化
  • 不阻碍操作:动画过程中或结束后,用户都可以继续交互
  • 带来价值:让界面更清晰或更令人愉悦

评审时,发现以下问题应立即指出:

  • 确切属性已知,却使用 transition-all
  • 进入动画从 scale(0) 开始,而非大约 scale(0.95) 并配合透明度变化
  • 常规 UI 动效持续时间超过 300ms
  • 未进行悬停能力检测便使用悬停动画
  • 由键盘触发的操作使用指针式动画
  • 弹出层、工具提示或菜单从错误的原点开始缩放
  • 对频繁触发的控件使用关键帧动画,而可逆过渡会更合适
  • 父元素的悬停动画导致子元素闪烁或变形,而将动画放在子元素层会更干净
  • 负载较高时使用 Motion 的 x 或 y 样式更新,而使用合成后的 transform 字符串会更安全
  • 进入和退出使用相同的时长,而退出动画本应更快
  • 列表子项同时出现,而小幅且有上限的错开动画能更清晰地呈现顺序
  • 立即卸载 React 组件,导致列表项、对话框、Toast 或弹出层无法播放退出动画
  • 对话框、弹出层或可移除列表项使用 transition: all

请记住:最好的 UI 动画通常浑然天成,而非刻意吸引注意。带着目的设计动画,调整好响应速度,尊重无障碍需求,让动效为产品服务,而不是喧宾夺主。

输出约定

当用户要求提供动态方案、动态系统或重要的动画实现时,请按以下格式回复:

  1. 意图:动态效果应引导的用户感知或行为
  2. 动态规范:持续时间、缓动令牌、距离、触发条件及受影响的元素
  3. 实现:具体的 Tailwind、Tailwind 关键帧、WAAPI 或 View Transition 代码
  4. 无障碍回退:减少动态效果偏好及不支持相关 API 时的行为
  5. QA 检查清单:性能、易用性、焦点、键盘和跨设备检查

如果工作涉及大量编舞,请使用 motion choreography 中更严格的分镜格式:分镜、时间线规范、实现计划、无障碍与回退方案,以及验证计划。

评论

支持 Markdown