L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Design et création · SKILL.md

animation-craft

animation-craft

动画工艺元技能——整合术语转换(animation-vocabulary)、设计工程(emil-design-eng)、 质量审查(review-animations)三阶段流水线。把模糊的动效需求变成精确的动画代码, 再经过10条硬标准审查,输出 Before→After→Why 优化建议。 解决 AI 生成动画"生硬、缓动不对、时长不合理"的常见问题。 Trigger keywords: 动画审查, 动效优化, animation review, 动画不自然, 动效太生硬, animation craft, 动画质量, 动效术语, 缓动函数, 动画时长, prefers-reduced-motion, 动画质感, 微交互动效, animation quality, motion design review…

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: animation-craft description: > 动画工艺元技能——整合术语转换(animation-vocabulary)、设计工程(emil-design-eng)、 质量审查(review-animations)三阶段流水线。把模糊的动效需求变成精确的动画代码, 再经过10条硬标准审查,输出 Before→After→Why 优化建议。 解决 AI 生成动画"生硬、缓动不对、时长不合理"的常见问题。 Trigger keywords: 动画审查, 动效优化, animation review, 动画不自然, 动效太生硬, animation craft, 动画质量, 动效术语, 缓动函数, 动画时长, prefers-reduced-motion, 动画质感, 微交互动效, animation quality, motion design review, 动画不够丝滑, 这个动画怪怪的, 动效帮我看看, review my animations, CSS动画优化, spring animation, 弹性动画, 阻尼动画. allowed-tools:

  • Read
  • Write
  • Edit
  • Bash
  • Glob
  • Grep metadata: category: design source: https://github.com/emilkowalski/skills (MIT) upstream-author: Emil Kowalski (Vercel → Linear, Sonner/Vaul author) version: "1.0.0" license: MIT

Animation Craft — 动画工艺元技能

整合 Emil Kowalski 三件套为一站式动画工艺流水线。AI 写的动画代码不够好?用这套规则让它变好。 上游来源:emilkowalski/skills (MIT, 4500+ ⭐)

核心理念

"AI 不会自动写出有审美的动画——它需要一套工艺规则。
 这套规则 = 精确的术语 + 正确的物理参数 + 严格的审查标准。"
                                                  — Emil Kowalski

动画工艺的三个层次,缺一不可:

  • 说对词 → AI 才能理解你要什么(词汇层)
  • 做对事 → AI 才能产出正确的代码(工程层)
  • 验质量 → 确保输出达到工艺标准(审查层)

工作流程总览

用户描述动效需求
       │
       ▼
┌─────────────────────────────────┐
│ Phase 1: Vocabulary 术语转换     │
│ 模糊感觉 → 精确动画术语         │
│ "弹出来" → spring scale-in      │
│ "一个个出来" → staggered reveal  │
└──────────┬──────────────────────┘
           │
           ▼
┌─────────────────────────────────┐
│ Phase 2: Design-Eng 设计工程    │
│ 按工艺规则生成/优化动画代码      │
│ 时长·缓动·GPU属性·无障碍        │
└──────────┬──────────────────────┘
           │
           ▼
┌─────────────────────────────────┐
│ Phase 3: Review 质量审查        │
│ 10条硬标准逐项审查              │
│ 输出 Before → After → Why       │
└─────────────────────────────────┘

路由逻辑

根据用户输入自动判断从哪个阶段进入:

用户说什么从哪开始
"这个动效叫什么?" / "用什么术语描述这个效果?"Phase 1 → 2 → 3(完整流程)
"帮我写一个弹窗动画" / "做一个下拉菜单的动效"Phase 1(快速术语确认)→ Phase 2
"审查一下这个组件的动画" / "这个动效怪怪的"Phase 3(直接审查)
"优化这段动画代码"Phase 2(优化已有代码)→ Phase 3

Phase 1: Vocabulary — 术语转换

目标:把"模糊的感觉"翻译成"精确的动画术语",让 AI 准确理解你的意图。

为什么这一步至关重要

同样的动画需求,用不同方式描述,AI 的输出质量天差地别:

❌ 模糊描述✅ 精确术语AI 理解差异
"弹出来"spring scale-in with ease-out模糊→随机实现 / 精确→可预测的弹性缩放
"一个个出来"staggered entrance, 50ms delay per item模糊→可能同时出现 / 精确→明确逐个延迟
"页面切换"shared element transition模糊→简单fade / 精确→元素在页面间持续变形
"菜单展开"origin-aware scale-in from trigger模糊→从屏幕中心缩放 / 精确→从触发按钮位置缩放
"列表滚动"rubber-banding at boundary模糊→硬边界停止 / 精确→iOS风格弹性过冲
"卡片出现"scale(0.95→1) + opacity(0→1), ease-out, 200ms模糊→可能从scale(0)开始(无体积感)

术语词汇表

入场/出场 (Enter/Exit)

感觉描述精确术语推荐参数
"淡入"fade inopacity 0→1, 150-300ms
"滑入"slide intranslateY(10px→0) + opacity, ease-out
"弹入"spring scale-inscale(0.95→1), spring, bounce: 0-0.2
"放大出现"scale-up revealscale + opacity, transform-origin: trigger
"从触发位置展开"origin-aware scale-intransform-origin 动态设置

序列动画 (Sequencing)

感觉描述精确术语推荐参数
"一个个出来"staggered entrance30-80ms delay per item
"依次展开"sequential revealcascade, 50-100ms stagger
"波浪效果"wave animationstagger + translateY, 正弦分布延迟

状态切换 (State Transitions)

感觉描述精确术语推荐参数
"页面切换"shared element transitionFLIP 动画模式
"列表重排"layout animationspring, bounce: 0
"展开/收起"collapse/expandheight auto→0, 或用 clip-path inset
"切换Tab"tab transitionclip-path inset + fade

反馈 (Feedback)

感觉描述精确术语推荐参数
"按下有反应"press feedbackscale(0.97), 100ms ease-out
"点击涟漪"ripple effectradial-gradient expand + fade
"拉到顶弹一下"rubber-banding过冲 + spring 回弹
"摇晃表示错误"shaketranslateX(±5px), 3-4次, 300ms

缓动 (Easing)

感觉描述精确术语CSS / JS
"慢慢开始"ease-incubic-bezier(0.4, 0, 1, 1)
"慢慢结束"ease-outcubic-bezier(0, 0, 0.2, 1)
"平滑过渡"ease-in-outcubic-bezier(0.4, 0, 0.2, 1)
"弹性效果"spring / bouncespring({ bounce: 0.2 })
"匀速"linearcubic-bezier(0, 0, 1, 1)
"iOS抽屉"drawer easingcubic-bezier(0.32, 0.72, 0, 1)
"惯性滚动"momentum / decaydeceleration rate 0.998

滚动 (Scroll)

感觉描述精确术语推荐实现
"视差"parallaxtranslateY 反向, 速率比 0.5-0.8
"滚动到边界弹一下"rubber-banding渐进阻力函数
"吸附"snap scrollCSS scroll-snap
"滚动触发动画"scroll-driven animationCSS animation-timeline: scroll()

Phase 1 输出模板

## 🏷️ 术语翻译

**原始需求**: [用户原话]
**翻译结果**: [精确术语1] + [精确术语2] + [精确术语3]

**推荐参数**:
- 动画类型: [类型]
- 缓动: [easing]
- 时长: [duration]ms
- 属性: [只列 transform/opacity]

是否按此理解继续生成代码?

Phase 2: Design-Eng — 设计工程规则

目标:生成/优化动画代码,确保每一行动画都符合工艺标准。

规则 1:动画时长控制

UI 元素推荐时长原因
按钮按下反馈100-160ms高频操作,需即时响应
Tooltip 出现125-200ms辅助信息,不能干扰
下拉菜单展开150-250ms需感知但不拖沓
弹窗/Modal 进入200-500ms需建立空间感
Drawer/Sheet 滑出250-400ms需跟随手势节奏
页面切换300-500ms需传达导航方向
Toast 通知200-300ms 进入, 3-5s 停留信息传递优先

铁律:UI 动画不超过 300ms,除非是大面积布局变化(Modal/Drawer/页面切换)。

规则 2:缓动函数选择

入场动画 → ease-out (cubic-bezier(0, 0, 0.2, 1))
  元素从无到有,快速进入后平稳落位。用户等待的是结果,不是过程。

出场动画 → ease-in (cubic-bezier(0.4, 0, 1, 1))
  元素从有到无,快速启动后缓慢消失。用户已不需要它,让它快走。

状态切换 → ease-in-out (cubic-bezier(0.4, 0, 0.2, 1))
  元素在原地变形,对称的开始和结束。

弹性交互 → spring (bounce: 0-0.2)
  直接操作(拖拽/滑动),需要物理真实感。

铁律:UI 动画禁止使用 ease-in 作为入场缓动——它会让人感觉界面卡顿。

规则 3:只动画 GPU 友好属性

✅ 始终动画:
  - transform (translate, scale, rotate, skew)
  - opacity

❌ 绝不动画:
  - width, height → 触发 layout,掉帧
  - top, left, right, bottom → 触发 layout
  - margin, padding → 触发 layout
  - border-width → 触发 paint

⚠️ 谨慎使用:
  - box-shadow → 触发 paint,低端设备卡
  - filter: blur() → 触发 paint,只在必要时用
  - background-color → 触发 paint,时长需控制在150ms内

替代方案:

  • 需要"展开"效果?→ 用 transform: scaleY() 替代 height 动画
  • 需要"位移"?→ 用 transform: translate() 替代 top/left
  • 需要"淡入+模糊"?→ 用 opacity + 预设模糊静态层

规则 4:弹出层必须从触发位置展开

/* ❌ 错误:从屏幕中心弹出 */
.popover {
  animation: scaleIn 200ms ease-out;
  transform-origin: center; /* 没有空间感 */
}

/* ✅ 正确:从触发元素位置弹出 */
.popover {
  animation: scaleIn 200ms ease-out;
  transform-origin: var(--trigger-x) var(--trigger-y); /* 动态计算 */
}

适用场景:Popover、Dropdown Menu、Context Menu、Tooltip、Sheet。

规则 5:入场从 scale(0.95) 开始,不是 scale(0)

/* ❌ 错误:无体积感的缩放 */
@keyframes badEntrance {
  from { transform: scale(0); opacity: 0; }
  /* 元素凭空产生,没有物质感 */
}

/* ✅ 正确:有体积感的缩放 */
@keyframes goodEntrance {
  from { transform: scale(0.95); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
  /* 元素始终存在体积,视觉自然 */
}

规则 6:自定义缓动曲线优于内置 easing

:root {
  /* 内置 easing 通常不理想,改用精确 cubic-bezier */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
}

规则 7:弹簧物理参数指南

使用 spring 动画时的推荐参数(Framer Motion / Motion 等库):

交互类型Damping RatioResponse (s)Bounce
移动/重定位1.00.40
旋转0.80.40
Drawer/Sheet0.80.30
拖拽松手(慢速)1.00.40
拖拽甩出(快速)0.80.30.2
// 默认:无弹性的阻尼弹簧(最常用)
animate(el, { y: 0 }, { type: 'spring', bounce: 0, duration: 0.4 });

// 仅手势松手时有轻微弹性
animate(el, { y: target }, { type: 'spring', bounce: 0.2, duration: 0.4 });

规则 8:中断性 — 动画必须可重定向

CSS transition 的优势:可中断
  - 在 transition 运行时更新目标值,动画从中断点平滑重定向到新目标
  - 适用于:hover 状态、下拉菜单、悬浮卡片

CSS @keyframes 的劣势:不可中断
  - 已开始的 keyframe 无法被用户交互中断
  - 避免用于:交互式 UI 元素(除非是纯装饰性的)

Spring 的优势:天生可中断
  - spring 始终从当前值开始,天然支持中断
  - 适用于:手势驱动的 UI、拖拽、滑动

铁律:交互式 UI 元素禁止使用 @keyframes 做入场/出场。用 CSS transition 或 spring。

规则 9:进场和出场不对称

/* ✅ 好的设计:非对称 */
.menu-enter  { animation: slideDown 200ms ease-out; }    /* 从上方展开 */
.menu-exit   { animation: fadeOut 150ms ease-in; }       /* 直接淡出 */

/* ❌ 坏的设计:镜像反转 */
.menu-enter  { animation: slideDown 200ms ease-out; }
.menu-exit   { animation: slideUp 200ms ease-in; }       /* 完全反向 = 无聊 */

为什么?进场是"建立空间关系",出场是"清除已不需要的元素"——两个时刻的用户心智完全不同。

规则 10:无障碍 — 尊重用户动效偏好

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  
  /* 但保留微妙的透明度变化(不涉及空间位移) */
  .toast { transition: opacity 200ms ease; }
}

额外考虑:

/* 减少透明度(对有视觉障碍的用户) */
@media (prefers-reduced-transparency: reduce) {
  .toolbar { background: white; backdrop-filter: none; }
}

/* 增强对比度 */
@media (prefers-contrast: more) {
  .card { border: 2px solid currentColor; }
}

Phase 3: Review — 10 条审查硬标准

目标:逐条审查动画代码,每一条必须是"通过"而非"差不多"。输出 Before → After → Why。

审查清单

#标准检查方法严重程度
1动画有目的这个动画是在反馈/解释/装饰?还是纯粹"炫"?🔴 阻断
2频率匹配高频操作(每天几十次)→ 极短或无动画;低频(onboarding)→ 可更丰富🔴 阻断
3缓动正确入场=ease-out, 出场=ease-in, 状态=ease-in-out。没有 UI 用 ease-in 入场🔴 阻断
4时长 ≤ 300ms除了 Modal/Drawer/页面切换,所有 UI 动画都检查时长🟡 严重
5transform-origin 正确Popover/Dropdown 的 transform-origin 指向触发元素,非默认 center🟡 严重
6可中断交互式元素不使用 @keyframes;动画进行中可以响应新的用户输入🟡 严重
7只用 transform + opacity检查是否动画了 width/height/top/left/margin 等 layout 属性🔴 阻断
8无障碍prefers-reduced-motion 处理正确;键盘操作不触发大型动画🟡 严重
9进场≠出场镜像进入和退出使用不同的动画,而非简单反转🟢 建议
10整体统一所有动画属于同一套缓动和时长体系,而非散乱混搭🟢 建议

审查输出格式

对每个问题,用 Before → After → Why 三段式输出:

## 🔍 动画审查报告

### 问题 #1: 弹窗使用 ease-in 入场
**严重程度**: 🔴 阻断

**Before**:
```css
.modal { animation: modalIn 300ms ease-in; }

After:

.modal { animation: modalIn 300ms ease-out; }

Why: ease-in 在开始阶段缓慢,让用户感觉"界面卡住了才反应过来"。 入场动画应用 ease-out——快速启动、平稳落位,用户感知的是结果而非过程。


### 常见问题速查

| 现象 | 根因 | 修复 |
|------|------|------|
| "动画感觉拖沓" | 用了 ease-in 且时长 >300ms | 改为 ease-out, ≤250ms |
| "弹窗从奇怪的地方出来" | transform-origin 是默认 center | 动态设为触发元素位置 |
| "列表展开时卡顿" | 动画了 height 属性 | 改用 scaleY + clip-path |
| "缩放没有体积感" | 从 scale(0) 开始 | 改为 scale(0.95) |
| "松手后元素跳变" | 没有速度传递 | 用 spring 继承手势速度 |
| "低端机动画掉帧" | 动画了 box-shadow/filter | 改用 opacity 淡入替代 |
| "transition: all 300ms" | 所有属性都在过渡 | 明确列出 transition-property |
| "键盘操作触发了大动画" | 未检查 reduced-motion | 用媒体查询移除动画 |

---

## 安装方式

### Claude Code

```bash
cp -r animation-craft/ ~/.claude/skills/animation-craft/

上游安装(获取 Emil 原始三件套)

npx skills add emilkowalski/skills

本 skill 为元技能包装层,整合并增强了上游三个技能的协作流程。


触发示例

Phase 1 触发(术语转换)

  • "这个弹出效果叫什么术语?"
  • "怎么描述'卡片依次滑入'这个动画?"
  • "iOS 那种拉到顶弹一下的效果怎么说?"

Phase 2 触发(设计工程)

  • "帮我写一个下拉菜单的展开动画"
  • "做一个弹窗的入场动效"
  • "给这个按钮加按下反馈"

Phase 3 触发(质量审查)

  • "审查一下这个组件的动画"
  • "这个动效怎么感觉怪怪的,帮我看看"
  • "review my animations for quality"
  • "检查这个页面的动效是否合规"
  • "这个动画在低端机上卡,帮我诊断"

完整流程触发

  • "帮我做一个有质感的弹窗动画"
  • "设计一套 Toast 通知的动效系统"
  • "优化整个项目的动画体验"

上游致谢

本 skill 基于 Emil Kowalski 的 skills 仓库 (MIT License),整合了以下三个上游技能:

上游技能在本 skill 中的角色
animation-vocabularyPhase 1: 术语转换
emil-design-engPhase 2: 设计工程规则
review-animationsPhase 3: 10条审查标准

Emil Kowalski 是 Sonner (React toast)、Vaul (React drawer) 的作者,前 Vercel 设计工程师,现 Linear Web 团队成员。他的设计工程哲学浓缩在这三个技能中。

Skills enregistrées