1实现原理 · 为什么它能做到
给交互动效定硬性时间窗与合成器约束(100–250ms、只动 transform/opacity、按压即时 0.96、进出非对称),把手感转成可检查的参数
Duration: UI micro-interactions live in **100–250ms**. Anything over ~400ms feels laggy for a click response.
Framer Motion 侧以手势、弹簧、AnimatePresence 三件套为骨架,弹簧用 stiffness/damping 两个直觉参数调
whileTap={{ scale: 0.96 }}
布局动画是 Framer Motion 的杀手锏:layout 自动把位置与尺寸变化转成 transform,layoutId 让两个组件之间做共享元素(magic move)过渡
{!open && <motion.div layoutId="card" onClick={() => setOpen(true)} />}
纯 CSS 路径也能做进场与退场(含 display 切换):@starting-style 提供首次渲染的起始值,transition-behavior: allow-discrete 让离散属性参与过渡
transition-behavior: allow-discrete;
把加载到成功到失败当作同一物体的连续状态(按钮变形 spinner 到 checkmark),而不是画面跳切;并强制 reduced-motion 守卫
Loading → success → error should be one continuous motion (e.g. a button morphs spinner → checkmark), not a jump cut.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| package | motion(Framer Motion,v11+ 以 motion/react 导入) |
| network | 交付页从 CDN 取 React 与 motion(正文点名 esm.sh;产物期引用,不判级) |
| api | 现代 CSS 原语:@starting-style、transition-behavior: allow-discrete、@property、popover/dialog 的 overlay 离散属性 |
| cli | npx / Playwright(宿主侧截图工具)与仓库根 scripts/ 助手(seek-shot.sh、contact-sheet.sh 依赖 ffmpeg) |
4风险提醒 风险提醒:绿色 · 放心使用
- 浏览器支持声明前后不一致且无源码依据(见 second_pass) — @starting-style 与 allow-discrete 的支持面在 SKILL.md 与 references 描述不同,旧浏览器需要自备降级(文档要求使用者自行核实)。
- 交付页若走 esm.sh 载入 React 与 motion,等于把渲染管线交给第三方 CDN — 单文件演示便利,但产物期依赖远端模块(供应链加离线不可用),且 Framer Motion 体积不小,不适合直接搬进生产。
- Framer Motion 的 layout 性能与视觉副作用 — layout 动画在列表规模大或频繁变更时带来持续变换与重排开销,并会拉伸圆角与文字;文档给了缓解手段但未给规模阈值。
- Packaged helper 语义不匹配(见 second_pass) — helper 是时间冻结(?t=N 秒),本 skill 主要用状态冻结(?state=),照抄命令得不到想要的画面。
5第二遍独立确认
- [unlocatable] transition-behavior: allow-discrete 与 @starting-style 的支持面 — SKILL.md 写 Baseline in Chrome/Edge/Safari、references 写 Baseline-available in current Chrome/Edge/Safari/Firefox——两处描述不同(SKILL.md 未含 Firefox),且均无源码内依据。正文要求读者 verify @starting-style and allow-discrete for your support floor,即文档自己把核实责任交给使用者,故按文档声明记录并在 risks 提示。
- [ok] layout 造成圆角与文字变形的告诫是否与配方一致 — SKILL.md 的 Gotcha 段与 references 的 magic-move/layout 小节都提示需子元素反向缩放或改用 layout="position";references 另给 useMotionValue 加 useSpring 的免重渲染建议,互不矛盾。
- [ok] 验收方式与动效性质是否匹配(状态驱动 vs 时间驱动) — SKILL.md 明写 A micro-interaction's frames are its states (idle / hover / pressed / open) 并给 ?state= 方案,同时保留 CSS 循环动画的 animationDelay 加 paused 冻结写法,两路都对得上其讨论的动效类型。
- [discrepancy] Packaged helper 的路径基准与语义 — SKILL.md 写 scripts/seek-shot.sh anim.html 0 1.5 3(秒制、时间冻结),但本 skill 的验收是状态冻结(?state=open),helper 与之不匹配;且 scripts/ 在仓库根,单装形态下相对路径亦不成立。
6结论
17fbed1b9f12f5ad…b6dba3eb75