animation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Animation Implementation with Motion

基于Motion的动画实现

Use the Motion library (https://motion.dev) for all animation work.
所有动画工作均使用Motion库(https://motion.dev)完成。

Quick Start

快速开始

React (Primary):
jsx
import { motion } from "motion/react"

// Basic animation
<motion.div animate={{ opacity: 1, y: 0 }} />

// With transition config
<motion.div
  animate={{ x: 100 }}
  transition={{ type: "spring", stiffness: 100 }}
/>
React(首选):
jsx
import { motion } from "motion/react"

// Basic animation
<motion.div animate={{ opacity: 1, y: 0 }} />

// With transition config
<motion.div
  animate={{ x: 100 }}
  transition={{ type: "spring", stiffness: 100 }}
/>

Core Patterns

核心模式

1. Spring Physics (Preferred)

1. 弹簧物理动画(首选)

jsx
<motion.div
  animate={{ scale: 1 }}
  transition={{
    type: 'spring',
    stiffness: 260,
    damping: 20,
  }}
/>
Spring presets:
  • Gentle:
    stiffness: 120, damping: 14
  • Wobbly:
    stiffness: 180, damping: 12
  • Stiff:
    stiffness: 300, damping: 20
jsx
<motion.div
  animate={{ scale: 1 }}
  transition={{
    type: 'spring',
    stiffness: 260,
    damping: 20,
  }}
/>
弹簧预设:
  • Gentle:
    stiffness: 120, damping: 14
  • Wobbly:
    stiffness: 180, damping: 12
  • Stiff:
    stiffness: 300, damping: 20

2. Gesture Interactions

2. 手势交互

jsx
<motion.div
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  drag="x"
  dragConstraints={{ left: -100, right: 100 }}
/>
jsx
<motion.div
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  drag="x"
  dragConstraints={{ left: -100, right: 100 }}
/>

3. Layout Animations

3. 布局动画

jsx
<motion.div layout>{/* Content that changes position/size */}</motion.div>
jsx
<motion.div layout>{/* Content that changes position/size */}</motion.div>

4. Scroll-Linked Effects

4. 滚动联动效果

jsx
import { useScroll, useTransform } from "motion/react"

const { scrollYProgress } = useScroll()
const opacity = useTransform(scrollYProgress, [0, 1], [1, 0])

<motion.div style={{ opacity }} />
jsx
import { useScroll, useTransform } from "motion/react"

const { scrollYProgress } = useScroll()
const opacity = useTransform(scrollYProgress, [0, 1], [1, 0])

<motion.div style={{ opacity }} />

5. Stagger Children

5. 子元素Stagger动画

jsx
<motion.ul
  variants={{
    visible: { transition: { staggerChildren: 0.07 } },
  }}
>
  {items.map((item) => (
    <motion.li
      key={item}
      variants={{
        hidden: { opacity: 0, y: 20 },
        visible: { opacity: 1, y: 0 },
      }}
    />
  ))}
</motion.ul>
jsx
<motion.ul
  variants={{
    visible: { transition: { staggerChildren: 0.07 } },
  }}
>
  {items.map((item) => (
    <motion.li
      key={item}
      variants={{
        hidden: { opacity: 0, y: 20 },
        visible: { opacity: 1, y: 0 },
      }}
    />
  ))}
</motion.ul>

6. Enter/Exit Animations

6. 进入/退出动画

jsx
import { AnimatePresence } from 'motion/react';

<AnimatePresence>
  {show && <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} />}
</AnimatePresence>;
jsx
import { AnimatePresence } from 'motion/react';

<AnimatePresence>
  {show && <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} />}
</AnimatePresence>;

Animation Properties

动画属性

Transform (GPU-accelerated, performant):
  • x, y, z
    - Translate
  • scale, scaleX, scaleY
    - Scale
  • rotate, rotateX, rotateY, rotateZ
    - Rotation
  • skew, skewX, skewY
    - Skew
Visual (use sparingly, can affect performance):
  • opacity
  • background, backgroundColor
  • color
  • borderRadius
SVG-specific:
  • pathLength
    - For path drawing animations
  • pathOffset
    - Offset the path
  • pathSpacing
    - Spacing between dashes
变换属性(GPU加速,性能优异):
  • x, y, z
    - 位移
  • scale, scaleX, scaleY
    - 缩放
  • rotate, rotateX, rotateY, rotateZ
    - 旋转
  • skew, skewX, skewY
    - 倾斜
视觉属性(谨慎使用,可能影响性能):
  • opacity
  • background, backgroundColor
  • color
  • borderRadius
SVG专属属性
  • pathLength
    - 用于路径绘制动画
  • pathOffset
    - 路径偏移
  • pathSpacing
    - 虚线间距

Accessibility

无障碍适配

Always respect user preferences:
jsx
<motion.div
  animate={{ x: 100 }}
  transition={{
    type: 'spring',
    // Disables animation if user prefers reduced motion
    duration: 0,
  }}
/>
Motion automatically handles
prefers-reduced-motion
. Springs become instant transitions.
始终尊重用户偏好:
jsx
<motion.div
  animate={{ x: 100 }}
  transition={{
    type: 'spring',
    // Disables animation if user prefers reduced motion
    duration: 0,
  }}
/>
Motion会自动处理
prefers-reduced-motion
设置。弹簧动画会变为即时过渡效果。

Performance Tips

性能优化技巧

  1. Animate transforms/opacity only when possible (GPU-accelerated)
  2. Use
    layout
    prop
    instead of animating width/height manually
  3. Avoid animating during scroll when possible
  4. Use
    will-change: transform
    for complex animations (Motion handles this)
  5. Limit simultaneous animations - stagger instead of all-at-once
  1. 尽可能仅对变换/透明度属性执行动画(GPU加速)
  2. 使用
    layout
    属性
    替代手动动画宽度/高度
  3. 尽可能避免在滚动时执行动画
  4. 为复杂动画添加
    will-change: transform
    (Motion会自动处理此设置)
  5. 限制同时执行的动画数量 - 采用stagger方式而非一次性全部执行

Design Principles (Brief)

设计原则(简述)

When to Animate

何时使用动画

  • State transitions (loading → success)
  • Spatial changes (entering/exiting view)
  • Drawing attention (sparingly)
  • Confirming user action
  • 状态切换(如加载→成功)
  • 空间变化(如进入/退出视图)
  • 吸引注意力(适度使用)
  • 确认用户操作

When NOT to Animate

何时不使用动画

  • Repeated actions after first occurrence
  • Performance-critical paths
  • User-controlled scrolling
  • Every single interaction (restraint matters)
  • 首次出现后的重复操作
  • 性能关键路径
  • 用户控制的滚动操作
  • 每一次交互(需克制使用)

Timing Guidelines

时长指南

  • Micro-interactions: 150-250ms
  • Panel/modal transitions: 200-300ms
  • Page transitions: 300-500ms
  • Springs: Let physics determine duration
  • 微交互:150-250ms
  • 面板/模态框过渡:200-300ms
  • 页面过渡:300-500ms
  • 弹簧动画:由物理特性决定时长

Spring vs Duration

弹簧动画 vs 固定时长

  • Use springs for: Interactive elements, gestures, layout changes
  • Use duration for: Intentional sequences, choreography, loaders
See
principles.md
for detailed animation philosophy.
  • 弹簧动画适用于:交互元素、手势、布局变化
  • 固定时长适用于:有意图的序列动画、编排动画、加载器
详细的动画设计理念请参考
principles.md

Common Patterns

常见模式

Loading state:
jsx
<motion.div
  animate={{ rotate: 360 }}
  transition={{
    repeat: Infinity,
    duration: 1,
    ease: 'linear',
  }}
/>
Toast notification:
jsx
<motion.div
  initial={{ x: 400, opacity: 0 }}
  animate={{ x: 0, opacity: 1 }}
  exit={{ x: 400, opacity: 0 }}
  transition={{ type: 'spring', stiffness: 300, damping: 30 }}
/>
Drawer:
jsx
<motion.div
  initial={{ x: '-100%' }}
  animate={{ x: 0 }}
  exit={{ x: '-100%' }}
  transition={{ type: 'spring', damping: 25 }}
/>
Accordion:
jsx
<motion.div
  animate={{ height: isOpen ? 'auto' : 0 }}
  transition={{ type: 'spring', bounce: 0 }}
  style={{ overflow: 'hidden' }}
/>
加载状态:
jsx
<motion.div
  animate={{ rotate: 360 }}
  transition={{
    repeat: Infinity,
    duration: 1,
    ease: 'linear',
  }}
/>
提示通知(Toast):
jsx
<motion.div
  initial={{ x: 400, opacity: 0 }}
  animate={{ x: 0, opacity: 1 }}
  exit={{ x: 400, opacity: 0 }}
  transition={{ type: 'spring', stiffness: 300, damping: 30 }}
/>
侧边抽屉:
jsx
<motion.div
  initial={{ x: '-100%' }}
  animate={{ x: 0 }}
  exit={{ x: '-100%' }}
  transition={{ type: 'spring', damping: 25 }}
/>
折叠面板:
jsx
<motion.div
  animate={{ height: isOpen ? 'auto' : 0 }}
  transition={{ type: 'spring', bounce: 0 }}
  style={{ overflow: 'hidden' }}
/>

Resources

参考资源

Quick Troubleshooting

快速排查指南

Animation not running?
  • Check if element is conditionally rendered (use AnimatePresence)
  • Verify target values are different from initial values
  • Check for CSS that might override (e.g.,
    !important
    )
Performance issues?
  • Stick to transforms and opacity
  • Use
    layout
    prop instead of animating dimensions
  • Check browser DevTools Performance tab
Layout animations flickering?
  • Ensure parent has
    position: relative
  • Add
    layout
    to both parent and child if needed
  • Check for conflicting CSS transitions
动画未运行?
  • 检查元素是否为条件渲染(使用AnimatePresence)
  • 验证目标值与初始值是否不同
  • 检查是否有CSS覆盖(如
    !important
性能问题?
  • 仅对变换和透明度属性执行动画
  • 使用
    layout
    属性替代动画尺寸变化
  • 查看浏览器DevTools的性能面板
布局动画闪烁?
  • 确保父元素设置了
    position: relative
  • 必要时为父元素和子元素都添加
    layout
    属性
  • 检查是否存在冲突的CSS过渡效果

Notes

说明

  • Motion is MIT licensed, production-ready
  • Hybrid engine: 120fps, GPU-accelerated
  • TypeScript support built-in
  • Tree-shakable for optimal bundle size
  • Works with React 18+ (including Suspense)
  • Motion采用MIT许可证,可用于生产环境
  • 混合引擎:支持120fps,GPU加速
  • 内置TypeScript支持
  • 支持Tree-shaking,优化包体积
  • 兼容React 18+(包括Suspense)