microinteraction-motion-designer
Use when turning a product interaction, prototype, UI audit, or implementation request into intentional, implementable motion behavior for feedback, navigation, loading, gestures, state changes, reduc
SKILL.mdmicrointeraction-motion-designer/SKILL.md
GitHub微动效设计器
中文简介
微动效设计器:把“更丝滑”转成有目的、可打断、可降级和可验收的动效契约。它用动效解释反馈、空间层级、进度或状态连续性,不把动画当作掩盖性能、信息架构或产品逻辑问题的装饰。
使用背景
当主流程、状态或组件已基本明确,需要把体验目标交给设计师、Figma 制作人、Codex 或前端工程师实现、审查或测试时使用。它可接收 prototype-brief-builder 的页面/组件状态与任务流,输出给 spec-to-implementation-plan、test-generator 和 code-review-assistant。
核心原则
- 每段动效先回答它在传达反馈、连续性、空间层级、进度或状态变化中的哪一项;回答不了就不添加。
- 用户直接操控的对象必须连续跟随输入;系统驱动的变化才使用预设时长和缓动。
- 时长、位移、easing 和弹簧参数共同表达距离、层级和紧迫度,不能只写“高级”“自然”或“有阻尼感”。
- 当前状态、目标状态、取消和完成必须可追溯;新意图优先于旧动画,绝不让过期动画覆盖最新状态。
prefers-reduced-motion、低端设备和长列表不是事后补丁:它们从规格开始就有等价的信息反馈与性能预算。
适用场景
- 为列表、搜索结果、卡片或表单状态设计首次可见进入、加载替换和提交反馈。
- 为 Tab、抽屉、弹层、详情返回或同级内容切换定义空间方向、层级和可打断过渡。
- 为拖拽面板、滑块、排序或返回手势定义连续跟手、边界阻尼、速度和吸附规则。
- 审查已有 CSS、Motion、Reanimated 或原生动效的目的、参数、性能、可访问性和测试缺口。
- 为 Codex、Cursor 或前端团队生成只改相关状态/组件的实现提示、状态机和验收标准。
不适用场景
- 需要先决定用户任务、信息架构、页面层级或业务状态时,先用
prototype-brief-builder或prd-builder;动效不修复不清楚的流程。 - 只有“给所有页面加高级动效”的要求时,不直接全页铺开。先收敛到具体任务、关系、频率、性能预算和一处可验证的关键过渡。
- 抖动、闪烁、复杂转场不能掩盖加载慢、错误率高、布局跳动或无反馈的业务问题;先修复根因或改用静态状态、进度和可恢复操作。
- 需要品牌片头、广告片或纯视觉影片时,不要把它伪装成产品微动效规格。
输入要求
先收集以下输入;没有的事实标为 [待确认],并说明其影响和补齐动作:
- 用户任务、界面/组件、当前与目标状态、触发者、成功/失败后果和该交互的使用频率。
- 动效要传达的目的、空间关系(同级、进入下级、覆盖层或直接操控)和不可接受的感受。
- 平台、输入方式、技术栈、现有设计系统/动效 token、目标视口和可用实现库。
- 正常、加载、空、错误、取消、权限和完成状态;手势需提供边界、snap point、速度单位和冲突手势。
prefers-reduced-motion策略、目标设备档位、列表规模、性能预算和已知低端设备/浏览器限制。- 可观察的验收方式:视觉/交互测试、性能测量、无障碍检查和允许的回退行为。
信息不足时的处理
- 只给“更高级”或“全页动效”: 只输出动效意图卡和需确认项,不输出全站模式清单。要求选定一个高频任务、一个进入/退出关系和成功指标;默认建议只试点一个关键转场。
- 没有状态或触发: 暂停选择时长和弹簧。先列出当前状态、事件、守卫、目标状态、取消事件和可见反馈;没有这些字段时只给问题清单。
- 没有性能或设备信息: 使用保守基线:仅
transform/opacity、首屏可见项、无无限循环、无滚动监听重排;把设备档位和帧预算标为[待确认]。 - 没有减少动态策略: 默认将非必要位移、缩放、视差、循环和弹簧回弹降为即时状态或不超过
100ms的透明度变化;关键状态同时保留文本、颜色、图标、焦点或读屏反馈。 - 没有手势边界或冲突规则: 不编造阻尼、阈值或吸附点。只输出待确认的范围、单位、优先级和取消规则,不能给“自然拖拽”的实现承诺。
工作流
- 建立动效意图卡。 写明任务、状态差异、触发、用户可感知的目的、层级、频率、非目标、风险和未知项;先拒绝无目的全页动画。
- 绘制状态与空间关系。 为每个
M-*记录当前状态、事件、守卫、目标状态、视觉层级、进入/退出方向、取消事件和完成后状态;直接操控使用连续进度而非离散 keyframe。 - 选择最小模式并参数化。 读取
references/motion-patterns.md,为位移、透明度、时长、延迟、easing 或弹簧写目标运行时/库/API、求解器语义、参数单位和值;弹簧必须登记目标值、实际初速度、rest 阈值和最大 settle 时间,让距离和层级决定时长。 - 设计中断、手势与恢复。 说明重定向、重复点击、导航返回、数据替换、失焦、卸载和手势取消时如何停止、从当前视觉值续接或立即落到最新状态;旧完成回调不得覆盖新状态。
- 定义无障碍与性能分层。 为完整、减少动态和低端档分别给出等价反馈、属性、范围、帧/主线程预算和触发降级条件;优先减少数量、距离和连续计算,不降低状态可见性。
- 编排实现与验收。 选择最轻的现有 API,写状态机、清理/取消、测试钩子和验收;读取
references/checklists.md,再用references/templates.md输出交接物。
专业判断规则
动效目的与空间层级
| 关系 | 应传达 | 默认方向与范围 | 不应使用 |
|---|---|---|---|
| 按压/提交反馈 | 操作已被识别 | 80-160ms 的色彩、opacity 或 scale(0.98) |
用长转场延迟提交结果 |
| 同级切换 | 当前内容替换但仍在同一上下文 | 160-240ms 交叉淡入或 4-12px 同向位移 |
伪造页面深度的 push |
| 进入/返回下级 | 前进/后退层级 | 220-320ms,前进和返回方向互为镜像 |
两页同时向同一方向移动 |
| 覆盖层/抽屉 | 前景接管、背景仍存在 | 180-280ms,遮罩与表面同一进度 |
把覆盖层当完整页面导航 |
| 直接操控 | 手指/指针与对象一一对应 | 每帧跟随,释放后才使用弹簧 | 拖动中预设缓动或离散跳点 |
- 首次可见列表只动首屏的
4-8个可见项;每项160-220ms、24-48msstagger、8-12px最大位移。虚拟化、回访和滚动追加默认不重放进入动画。 - 距离越远、层级越深,时长可增加但通常不超过
320ms;高频反馈优先短于160ms。不要用超过400ms的普通 UI 转场制造“高级感”。 - 一个元素通常只保留一个主要变化和一个辅助变化,例如
translateY + opacity;避免同一时刻叠加缩放、模糊、旋转、阴影和位移。
Easing、弹簧与参数预算
- 进入和确认优先
cubic-bezier(0.2, 0, 0, 1);退出优先cubic-bezier(0.4, 0, 1, 1);同级替换可用cubic-bezier(0.2, 0, 0, 1),但不把 ease-in 用在用户等待的进入。 - 点击或导航的非手势动效必须给出
duration与 easing;禁止只写ease-out、spring或“有阻尼感”。 - 弹簧规格必须指定目标运行时/库/API与求解器语义,再给出
stiffness、damping、mass的 API 语义或单位、实际初速度(数值和单位)、目标值、restDelta、restSpeed和最大 settle 时间。不能写“spring”后让实现方猜求解器。 - 例如使用 Motion 的
type: "spring"时,写明该库的数值积分 spring 配置;对translateY,velocity使用px/s,目标用px,restDelta用px,restSpeed用px/s。示范起点可为stiffness: 260、damping: 28、mass: 1、restDelta: 0.5px、restSpeed: 5px/s,但只在这个 API 语义下有效。 - 不同运行时不可直接复制数值:先映射到目标 API 的模型,再以目标值、最大 settle 时间和可接受 overshoot 重新调参。若目标 API 只暴露
dampingRatio、响应时长或速度向量,记录字段映射、保留的感知目标和待验证参数;没有一对一映射时不得伪造damping或mass。 - 参数预算写进规格:单次交互最多一个弹簧,普通组件最多
320ms,循环仅用于仍在等待的可见加载态且可暂停;位移范围、stagger 总时长和并发元素数必须有上限。
手势连续性、中断与状态机
- 每个
M-*使用idle -> pending/dragging -> active/settling -> completed | cancelled | failed或等价状态;列出事件、守卫、副作用和可见反馈。状态不存在时不能声明“支持快速连续操作”。 - 新输入、路由变化、卸载、数据替换、
pointercancel、手势夺取和减少动态偏好变化都是明确取消事件。取消后停止 rAF/计时器、移除监听器、取消动画控制器,并只允许当前请求提交最终状态。 - 手势使用当前位置和实时速度;释放时按位置、速度和阈值选择目标 snap point。边界外采用单调阻尼,
pointercancel回到最后稳定点,不能触发成功操作。 - 反向操作从当前 presentation value 接续到新目标,而不是跳回起点;异步完成必须检查 request/transition id,过期回调只清理资源,不更新 UI。
Reduced Motion、低端设备与性能降级
| 档位 | 触发 | 允许的动效 | 必须保留的反馈 |
|---|---|---|---|
| 完整 | 无减少动态且性能协议允许 motionProfile=full |
已规格化的 transform/opacity、必要弹簧和首屏 stagger | 状态文案、图标、焦点/读屏与可操作性 |
| 减少动态 | prefers-reduced-motion: reduce 或平台设置 |
即时状态,或不超过 100ms opacity;无视差、无循环、无弹簧位移 |
同样的状态、层级、进度和错误/成功提示 |
| 低端降级 | 明确低档设备标记,或性能协议在稳定边界提交 motionProfile=low |
取消 stagger/模糊/阴影/连续滚动计算,只动首个关键对象或即时切换 | 同样的触发确认、内容可达性和恢复路径 |
- 优先动画
transform和opacity;避免按帧改top、left、width、height、大面积filter、布局查询或大量阴影。读写布局要分帧,滚动事件要合帧并可取消。 - 性能降级协议(产品基线,待目标产品验证,不是通用真理): 在每个动效交互作用域内,以
requestAnimationFrame时间戳采样;原生平台有帧指标时可接入同一记录,但必须标明来源。用最近12帧滑动窗口统计帧间隔;若其中至少3帧超过20ms,或设备被产品 profile 标为低档,则将降级标为pending。绝不在dragging中切档;只在当前 transition 完成、抽屉停在稳定 snap point 或下一次交互开始前提交motionProfile=low。 - 恢复生命周期: 采用
full -> pending-low -> low-cooling -> low-sampling -> restore-pending -> full。提交low的稳定边界立即开始低频探针;在前台/可见状态下,每250ms调度一次连续两个 rAF,只记录该 rAF 对的帧间隔,避免把250ms等待本身算作 long frame。无交互时探针仍持续,因此恢复不依赖下一次手势。冷却使用累计前台可见时间:low-cooling满5s后才开始记入恢复窗口。 low-sampling的每个干净探针累积到当前60帧窗口;两个完整窗口都没有超过20ms的帧时进入restore-pending。任何 long frame 重置当前和已完成恢复窗口,并重新进入low-cooling;窗口不足保持low-sampling。restore-pending只能在 idle、transition 完成或稳定 snap point 提交full,绝不在dragging/settling 中跳档。document hidden或 app background 时,暂停并清理 timeout/rAF/平台采样器,停止累计前台冷却时间,并重置当前和已完成恢复窗口;回到 visible/foreground 后保持low,从剩余冷却时间和新窗口重新开始。路由卸载、减少动态接管或销毁监控时同样清理所有句柄和 visibility/app-state 监听器。用假时钟和可控 rAF 在确定性测试中喂入5s前台时间及120个干净样本,验证restore-pending仅在稳定边界进入full。
输出契约
按 references/templates.md 输出,至少包含:
- 动效意图卡:任务、目的、空间层级、频率、非目标、性能/无障碍风险和
[待确认]。 M-*状态转换表:当前状态、事件、守卫、目标状态、进入/退出、取消、过期回调保护和恢复。- 参数表:对象、属性、起止值、距离、时长/延迟、easing,或目标运行时/库/API、求解器语义、完整弹簧字段、并发/循环预算和单位。
- 三档行为与性能协议:完整、减少动态、低端降级的触发条件、可见行为、等价反馈、采样源/窗口、阈值、低频恢复生命周期、隐藏/后台暂停清理、稳定边界、恢复冷却期和防抖。
- 实现边界:推荐 API、可取消资源、避免的属性、手势/导航协作、测试钩子和不修改的业务范围。
- 可观察验收:目的、层级、参数、快速操作/取消、减少动态、低端性能、键盘/读屏和视觉稳定性的检查。
质量门槛
- 不交付没有用户任务、动效目的、空间关系和状态转换的动画清单。
- 不接受“所有页面都做高级动效”作为规格;必须缩小为可测任务和有限关键关系,或明确拒绝并给出收敛问题。
- 不交付没有数值与单位的时长、距离、stagger、easing 或弹簧参数;弹簧还必须有目标运行时/库/API、求解器语义、目标、实际初速度、rest 阈值和最大 settle 时间。
- 不把一个平台的 stiffness/damping/mass 原样复制到另一平台;必须写字段映射和重新调参规则,或明确停止等待目标 API。
- 不交付只有“掉帧时降级”的性能方案;必须有交互作用域采样源、窗口、产品基线/待验证阈值、稳定切换点、低频恢复生命周期、无交互采样、隐藏/后台暂停清理、恢复条件、冷却期和防抖。
- 不交付只写“可打断”的方案;必须给出取消事件、资源清理、当前值续接/稳定点和过期回调保护。
- 不交付只在完整档工作的动效;减少动态和低端档必须保留等价状态反馈与可完成任务。
- 不以动画掩盖网络慢、布局跳动、错误恢复缺失或业务状态不清;先登记根因和静态替代。
- 交付前读取
references/checklists.md,并确认模板、示例和实现建议能覆盖列表进入、全页请求和低端/减少动态三类场景。
常见失败与修正
| 失败 | 修正 |
|---|---|
| “给所有页面加高级动效” | 拒绝全页默认化;从一个高频任务、一个层级关系和性能预算开始试点。 |
| 列表每次滚回都重新 stagger | 只动首次首屏可见项;虚拟化、回访和滚动追加保持静态。 |
| 只写“弹簧自然一点” | 指定运行时/API 与求解器,补齐参数 API 语义/单位、实际 velocity、目标、restDelta、restSpeed、最大 settle 时间和减少动态替代。 |
| 从 Web 配置复制到原生弹簧 | 记录目标 API 的字段映射与感知目标,按目标值、settle 时间和 overshoot 在目标平台重新调参。 |
| 连续掉帧就立即降级或恢复 | 以交互 rAF/平台帧指标采样,等待稳定边界切档,并用窗口、冷却期和防抖限制恢复。 |
| 只在一次拖拽中采样,却要求未来恢复窗口 | low 后启动可见前台的低频探针;隐藏/后台暂停清理并重置窗口,恢复仅在稳定边界提交。 |
| 快速点击后旧内容又出现 | 用 transition/request id 取消旧控制器,过期完成只清理不提交状态。 |
| 拖拽中有滞后或松手误触 | 拖动时直接映射位置,定义阈值、速度、snap point 和 pointercancel 稳定点。 |
| 低端设备只是不显示动画 | 保留状态文案、颜色/图标、焦点和错误/成功播报,并记录降级触发。 |
| 用 blur、布局属性和无限 shimmer 营造质感 | 改为有限的 transform/opacity;加载完成、离屏或性能降级时停止循环。 |
参考资料
references/usage-guide.zh.md:中文调用顺序、输入准备、三档选择与协作交接。references/motion-patterns.md:列表、层级、状态、手势与性能模式的选择规则和参数起点。references/templates.md:动效契约、状态机、降级表、实现提示和验收模板。references/checklists.md:目的、空间、参数、中断、无障碍、性能和测试质量门。references/examples.md:列表进入、全页高级动效请求和低端/减少动态的完整闭环示例。