Skip to content
返回构建教程

动画交接

把 Figma Smart Animate / Lottie 规格翻译成代码中的 Framer Motion 或 CSS 动画。

为什么

动画是设计转代码交接最有损部分,因在 Figma 规为时间曲线和关键帧但在代码实现为字符串。设计师规'200ms ease-out 带 50ms stagger',开发者写'transition: 0.2s'——完全漏 easing 和 stagger。有纪律方法是在 token 系统定义运动 token(时长、easing、stagger),在 Figma 和代码都引用,复杂序列用 Framer Motion 因 CSS transition 表达不了编排。没有它,动画感廉价不一致因每开发者选不同时间值。

何时使用

设计含非平凡运动(页面过渡、错列列表、弹簧物理)时。约 2-3 小时。静态设计可跳过。

如何做

1. 在 token 系统定义运动 token
   - duration.fast: 150ms、duration.base: 250ms、duration.slow: 400ms
   - easing.out: cubic-bezier(0, 0, 0.2, 1)、easing.spring: spring(1, 100, 10, 0)

2. Figma 里用 Smart Animate 并在画板名或注释文档化时间
   - 画板名"Card hover — 200ms ease-out"
   - 复杂路径动画(加载旋转、插画)导出 Lottie

3. 代码里编排序列用 Framer Motion,简单过渡用 CSS
   - Framer Motion:布局动画、共享布局、拖拽、手势、错列
   - CSS:hover、focus、简单 opacity/transform——无需 JS

4. 用 Framer Motion 的 staggerChildren 实现错列列表
   - container variants:{ hidden: {}, show: { transition: { staggerChildren: 0.05 } } }
   - item variants:{ hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0 } }

5. 尊重 prefers-reduced-motion:禁所有非必要动画
   - Framer Motion:useReducedMotion() hook → 换即时过渡
   - CSS:@media (prefers-reduced-motion: reduce) { * { transition: none !important } }

示例

// 运动 token(tokens.json)
{ "motion": { "duration": { "fast": "150ms", "base": "250ms" }, "easing": { "out": [0, 0, 0.2, 1] } } }

// Framer Motion 错列列表
import { motion } from "framer-motion";
const container = { hidden: {}, show: { transition: { staggerChildren: 0.05 } } };
const item = { hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0, transition: { duration: 0.25, ease: [0, 0, 0.2, 1] } } };
export function List({ items }) {
  return (
    <motion.ul variants={container} initial="hidden" animate="show">
      {items.map(i => <motion.li key={i.id} variants={item}>{i.label}</motion.li>)}
    </motion.ul>
  );
}

// 减少动画
import { useReducedMotion } from "framer-motion";
const reduce = useReducedMotion();
const transition = reduce ? { duration: 0 } : { duration: 0.25, ease: [0, 0, 0.2, 1] };

常见问题

  • ⚠一切用线性 easing,看起来机械——自然运动减速(ease-out)或过冲(spring)。
  • ⚠UI 反馈动画超 300ms,感迟钝——用户感知 >100ms 为延迟。
  • ⚠不尊重 prefers-reduced-motion,致前庭敏感用户运动病。
  • ⚠动画布局属性(width、top)而非 transform,因布局触发回流致卡。

最佳实践

  • ✓定义运动 token 并到处用——永不硬编码时长或 easing 在组件里。
  • ✓动画优先 transform 和 opacity——GPU 加速不触发回流。
  • ✓共享元素过渡(列表→详情)用 Framer Motion 的 layout prop——它替你处理 FLIP 技术。
  • ✓启用 prefers-reduced-motion: reduce 测试确保无动画应用可用。