apple-fluid-motionlisted
Install: claude install-skill yang20040317-svg/design-workflow
# Apple Fluid Motion(苹果流畅动效)
> 来源:WWDC Fluid Interfaces 演讲提炼。核心:从当前呈现值起、继承速度、可中断、弹簧实现。直接感、物理感、可预测性。
## 1. 响应性(消除延迟)
延迟一出现,直接操作感断崖消失;反馈必须在交互**过程**中连续发生,而非只在结束。
- **按下即响应**:在 `pointerdown` 而非 `click`/抬手时高亮。
- 清掉输入路径上的多余延迟:debounce、定时器、~300ms 点击延迟。
- 拖拽/滑块/抽屉与指针 1:1 实时更新。
```css
.button:active { transform: scale(0.97); transition: transform 100ms ease-out; }
```
## 2. 直接操作(1:1 跟踪)
「触摸与内容一起移动」,元素黏手指,尊重抓取点偏移。
- Pointer Events + `setPointerCapture`,指针离界也续跟。
- 记录近期 `pointermove` 的位置/时间史,用于释放时算速度。
```js
el.addEventListener('pointerdown', (e) => {
el.setPointerCapture(e.pointerId);
const grabOffset = e.clientY - el.getBoundingClientRect().top;
});
```
## 3. 可中断性(最重要原则)
任何动画随时可被抓、反向、重定向;思考与手势并行。
- **过渡中绝不锁输入**。
- **从当前呈现值(非目标值)起动画**,避免跳变。
- **避免用 CSS transition / @keyframes 做手势驱动动效**(无法平滑中断),用弹簧。
- 反向时混合速度,不硬切,避免「砖墙」感;选支持 velocity 重定标的弹簧库。
- **2D 运动分解为独立 X/Y 弹簧**。
## 4. 弹簧驱动(行为优于动画)
预排固定时长动画无法响应输入;弹簧通过改变目标保持连续。
- **阻尼比(damping ratio)**:`1.0` 临界无弹跳;`<1.0` 欠阻尼有弹跳。
- **响应(response)**:到达目标的秒数,非 duration,无固定时长。
- **默认**:多数 UI `damping 1.0`;仅手势带动量(甩动)时用 `~0.8`。
| 交互 | Damping | Response |
| --- | --- | --- |
| Move / reposition | 1.0 | 0.4 |
| Rotation | 0.8 | 0.4 |
| Drawer / sheet | 0.8 | 0.3 |
```js
animate(el, { y: 0 }, { type: 'spring', bounce: 0, duration: 0.4 });
animate(el, { y: target }, { type: 'spring', bounce: 0.2, duration: 0.4 });
```
Web 映射:Motion/Framer Motion 的 `bounce`+`duration` ≈ Apple 的 `damping`+`response`。
## 5. 速度交接(Velocity Handoff)
手势结束的动画必须以