Empro Labs 动效技能 是做什么的?
Web 动效设计技能。两个步骤:先编写动效规格 (ANIMATION.md),然后编写代码。
ANIMATION.md 是保存在项目中的文件。可手工编辑,可在其他项目中复用,也可被其他工具读取。
此文件中的路径相对于技能文件夹(~/.claude/skills/empro-labs-animation-skill/)。运行脚本时请使用绝对路径。
请求
用户通过斜杠命令发出的请求:
$ARGUMENTS
如果上方请求为空,则询问一个问题:什么应该移动,以及移动到哪里?然后开始阶段 A。
核心流程
阶段 A 理解输入 ──→ 阶段 B 编写 ANIMATION.md(用户批准)──→ 阶段 C 实现 ──→ 阶段 D 审核
启动检查(按此顺序)
- 项目是否有
ANIMATION.md?→ 按用户要求复用、编辑或重建它。 - 是否有来自 web-design 技能的
DESIGN.md?→ 继承其颜色、字体和风格方向。保持动效与之一致。 - 是否有动效令牌(
--motion-*变量或动效文件)?→ 复用它们。不要发明新值。 - 是否已有动效代码?→ 先运行
python scripts/analyze_motion.py <project> --inventory,以便在提出更改前了解现有情况。 - 以上都没有 → 阶段 A。
阶段 A:理解
输入可以是组合的:
| 输入 | 操作 |
|---|---|
| 参考 URL | 运行 python scripts/capture_motion.py --url [URL] --output ./motion-capture。读取 capture.json 获取真实时长、缓动函数、动画属性和滚动关联效果。使用 top.png 把握基调。 |
| 动效视频或截图 | 描述触发条件、大致时长和缓动感觉。与用户确认数字。 |
| 关键词(“干脆”、“电影感”) | 将其匹配到 references/motion-personalities.md 中的一种个性。 |
| 品牌名称(“像 Linear”) | 如果该网站可访问则抓取实时网站。如果不能,则请求一个参考 URL。不要凭记忆猜测品牌动效。 |
| 现有代码 | 运行盘点脚本并保留有效部分。 |
A1. 个性(最多问两个问题)
- 感觉: 平静、干脆、俏皮还是电影感?
- 页面类型: 内容密集(动效不干扰)还是展示型(动效可以引领)?
从 references/motion-personalities.md 中展示一到两个候选方案,每个附带一行原因。由用户确认。
A2. 交互层级(必需,不可跳过)
参见 references/interaction-tiers.md。
| 层级 | 体验 | 工具 |
|---|---|---|
| L1 微交互 | 悬停、聚焦、按下、切换、小状态变更 | 仅 CSS 过渡 |
| L2 编排型 | 进入和退出、交错列表、模态框、抽屉、路由变更、加载器 | CSS 关键帧、Web Animations API 或 GSAP 时间线 |
| L3 滚动故事 | 滚动关联的揭示、固定、视差、由时间线驱动的章节 | GSAP + ScrollTrigger,或 CSS 滚动驱动动画(带降级方案) |
L3 限制为每页最多两个固定章节。每个页面章节需在规格中声明其层级。
A3. 技术栈
检查 package.json 和框架(纯 HTML、React、Vue、Svelte、Next.js)。使用 references/tooling.md 选择工具。默认:CSS 和 Web Animations API。仅对 L3 或复杂时间线添加 GSAP。
阶段 B:编写 ANIMATION.md
遵循 references/animation-md-template.md。共十个章节:
- 动效个性与原则
- 动效令牌(时长、缓动、距离)
- 编排清单(表格:元素、触发条件、属性、时长、缓动、延迟、减少动效降级方案)
- 组件动效(默认、悬停、聚焦可见、活跃、禁用、进入、退出)
- 滚动行为
- 页面与路由过渡
- 性能预算
- 可访问性
- 应与不应(至少 8 项,其中至少 5 项为“不应”)
- 依赖项
向用户展示摘要并等待批准。然后将 ANIMATION.md 保存在项目根目录。
阶段 C:实现
- 随处使用令牌。 每个时长和缓动都应为变量,例如
var(--motion-duration-base)。组件内无魔术数字。 - 仅动画化廉价属性。 优先使用
transform和opacity。clip-path和filter允许用于小元素。除非 ANIMATION.md 记录了例外情况并附有理由,否则永远不要动画化width、height、top、left、margin或padding。 - 减少动效是第一个版本的一部分,而不是后续的补丁。 移除运动,保留状态变更。距离令牌在减少动效下归零,
templates/motion-tokens.css中的prefers-reduced-motion区块展示了该模式。 - 当项目尚无动效层时,使用起始文件:
templates/motion-tokens.css和templates/reveal.js。 - 循环需要退出方式。 任何
infinite动画在减少动效下停止或简化。任何运行时间超过五秒的循环都应有暂停控件。 - 清理 JavaScript。 在卸载时销毁 GSAP 时间线和 ScrollTrigger(使用
gsap.context()或useGSAP)。断开观察器并移除监听器。 - 将动效集中在一处。 将令牌放在一个文件中,将配方放在小模块中。不要将时间值分散到各个组件中。
阶段 D:审核
- 运行静态审核:
python scripts/analyze_motion.py <project> --strict。修复每个错误。审查每个警告,要么修复,要么在 ANIMATION.md 中说明理由。 - 运行浏览器检查:
- 启用减少动效(开发者工具 → 渲染 →
prefers-reduced-motion: reduce)。确认没有运动残留且内容仍然可见。 - 降级 CPU(4 倍)并在动效播放时录制 Performance 面板。查找长帧。
- 检查手机宽度(390 px)。查找来自动画元素的水平溢出。
- 启用减少动效(开发者工具 → 渲染 →
- 逐项检查
references/quality-checklist.md。 - 报告哪些通过了,哪些失败了,以及修复了哪些问题。
红线(每项必须通过)
- ANIMATION.md 中的每个动画都有减少动效降级方案。
- 仅动画化
transform、opacity以及记录的例外情况。 - 所有时长和缓动均来自令牌。
- 每个
infinite循环尊重减少动效,并且任何超过五秒的循环都应有暂停控件。 - 任何内容每秒闪烁不超过三次。
- 交互反馈在 100 毫秒内出现。微动画为 250 毫秒或更短。入场和路由过渡为 500 毫秒或更短。
- 仅悬停反馈具有键盘聚焦状态和触摸等效方案。
- 在宽度为 600 像素或更小时,无动画元素引起水平滚动,并且固定章节被禁用或简化。
- JavaScript 动画在卸载时被清理。
参考索引
仅读取当前阶段所需的文件。不要全部加载。
| 文件 | 内容 | 读取时机 |
|---|---|---|
references/animation-md-template.md | ANIMATION.md 输出模板(10 个章节) | 阶段 B |
references/motion-principles.md | 为什么以及何时动画化,时间和缓动规则 | 阶段 A 和 B |
references/interaction-tiers.md | L1、L2 和 L3 层级定义及代码模式 | 阶段 A2 和 B |
references/motion-personalities.md | 四种个性预设及令牌值 | 阶段 A1 和 B |
references/tooling.md | CSS vs WAAPI vs GSAP vs Motion vs View Transitions vs Lottie | 阶段 A3 |
references/component-recipes.md | 按钮、卡片、手风琴、模态框、抽屉、吐司、标签页、加载器 | 阶段 C |
references/gsap-recipes.md | GSAP 时间线、ScrollTrigger、matchMedia、React 清理 | 阶段 C(仅 GSAP) |
references/scroll-patterns.md | 揭示、进度条、粘性堆叠、视差、水平滚动 | 阶段 B(滚动)和 C |
references/performance.md | 帧预算、合成器友好规则、移动端降级 | 阶段 B 和 D |
references/accessibility.md | 减少动效、WCAG 动效标准、前庭触发条件 | 阶段 B 和 D |
references/quality-checklist.md | 100 点审核清单 | 阶段 D |
脚本
| 脚本 | 用途 | 需要 |
|---|---|---|
scripts/analyze_motion.py | 对项目的 CSS 和 JS 进行静态审核。查找布局动画、transition: all、无限循环、长时间以及缺少减少动效处理。--inventory 列出现有的时间值。 | Python 3(仅标准库) |
scripts/capture_motion.py | 记录实时 URL 上声明和正在运行的动画,滚动页面并检查在减少动效下哪些仍然运行。写入 capture.json 和 top.png。 | Python 3,pip install playwright,python -m playwright install chromium |
两个脚本都接受 --help。
模板
| 文件 | 用途 |
|---|---|
templates/motion-tokens.css | 令牌变量、基础关键帧、揭示规则和减少动效区块。复制到项目中。 |
templates/reveal.js | 无依赖的滚动揭示,使用 IntersectionObserver,尊重减少动效。 |
语言
用用户的语言编写 ANIMATION.md 和摘要。CSS、JavaScript 和令牌名称保持英文。
降级链
- 捕获脚本失败(无 Playwright,或站点阻止浏览器)→ 请求截图或简短屏幕录制,并从描述中构建。
- 参考使用了无法识别的动画库 → 说明情况,并询问是匹配感觉还是精确动效。
- 完全没有输入 → 询问一个关于感觉的问题,然后使用平静个性。