framer-motion-variants

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Framer Motion Variants

Framer Motion 动画变体

When to Use This Skill

何时使用此技能

Apply when building multi-step animations, coordinated animations across multiple elements, or when using variants for state-based animation control. Variants are Framer Motion's way of defining reusable animation states that can be choreographed.
Related skills: For core animation props use framer-motion-core; for React integration use framer-motion-react; for scroll-driven variants use framer-motion-scroll.
适用于构建多步骤动画、多元素协同动画,或使用变体实现基于状态的动画控制场景。变体是Framer Motion中定义可编排的可复用动画状态的方式。
相关技能: 核心动画属性请使用 framer-motion-core;React集成请使用 framer-motion-react;滚动驱动变体请使用 framer-motion-scroll

Defining Variants

定义变体

Variants are objects that define animation states:
jsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1
    }
  }
};

const item = {
  hidden: { opacity: 0, y: 20 },
  visible: { opacity: 1, y: 0 }
};

function Component() {
  return (
    <motion.div
      variants={container}
      initial="hidden"
      animate="visible"
    >
      {[1, 2, 3].map(i => (
        <motion.div key={i} variants={item} />
      ))}
    </motion.div>
  );
}
变体是定义动画状态的对象:
jsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1
    }
  }
};

const item = {
  hidden: { opacity: 0, y: 20 },
  visible: { opacity: 1, y: 0 }
};

function Component() {
  return (
    <motion.div
      variants={container}
      initial="hidden"
      animate="visible"
    >
      {[1, 2, 3].map(i => (
        <motion.div key={i} variants={item} />
      ))}
    </motion.div>
  );
}

Variant Types

变体类型

Static Variants

静态变体

jsx
const variants = {
  initial: { opacity: 0 },
  animate: { opacity: 1 },
  exit: { opacity: 0 }
};
jsx
const variants = {
  initial: { opacity: 0 },
  animate: { opacity: 1 },
  exit: { opacity: 0 }
};

Dynamic Variants

动态变体

jsx
const variants = {
  animate: (custom) => ({
    x: custom * 100,
    opacity: 1
  })
};
jsx
const variants = {
  animate: (custom) => ({
    x: custom * 100,
    opacity: 1
  })
};

Orchestration

动画编排

staggerChildren

staggerChildren

Stagger children animations:
jsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1,
      delayChildren: 0.2
    }
  }
};
实现子元素动画交错:
jsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1,
      delayChildren: 0.2
    }
  }
};

staggerDirection

staggerDirection

jsx
transition: {
  staggerChildren: 0.1,
  staggerDirection: -1  // 1 = forward, -1 = backward
}
jsx
transition: {
  staggerChildren: 0.1,
  staggerDirection: -1  // 1 = 正向, -1 = 反向
}

Repeating Animations

重复动画

jsx
const variants = {
  animate: {
    scale: [1, 1.5, 1],
    transition: {
      duration: 2,
      repeat: Infinity,
      repeatType: "loop"  // "loop" | "reverse" | "mirror"
    }
  }
};
jsx
const variants = {
  animate: {
    scale: [1, 1.5, 1],
    transition: {
      duration: 2,
      repeat: Infinity,
      repeatType: "loop"  // "loop" | "reverse" | "mirror"
    }
  }
};

repeatType Options

repeatType 选项

TypeBehavior
"loop"
Restart from beginning
"reverse"
Play forward then backward
"mirror"
Swap states on each repeat
类型行为
"loop"
从开头重新播放
"reverse"
先正向播放再反向播放
"mirror"
每次重复时切换状态

Keyframes

关键帧

Animate through multiple values:
jsx
<motion.div
  animate={{
    x: [0, 100, -50, 0],
    backgroundColor: ["#ff0000", "#00ff00", "#0000ff"]
  }}
  transition={{
    duration: 2,
    times: [0, 0.3, 0.6, 1]
  }}
/>
通过多个值实现动画:
jsx
<motion.div
  animate={{
    x: [0, 100, -50, 0],
    backgroundColor: ["#ff0000", "#00ff00", "#0000ff"]
  }}
  transition={{
    duration: 2,
    times: [0, 0.3, 0.6, 1]
  }}
/>

State Machine with custom

结合custom的状态机

jsx
const states = {
  idle: { scale: 1 },
  hovered: { scale: 1.1 },
  pressed: { scale: 0.95 }
};

function Component({ state }) {
  return (
    <motion.div
      variants={states}
      animate={state}
      custom={state}
    />
  );
}
jsx
const states = {
  idle: { scale: 1 },
  hovered: { scale: 1.1 },
  pressed: { scale: 0.95 }
};

function Component({ state }) {
  return (
    <motion.div
      variants={states}
      animate={state}
      custom={state}
    />
  );
}

Parent-Child Coordination

父子组件协同

jsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1,
      when: "beforeChildren"
    }
  }
};

const child = {
  hidden: { x: -20, opacity: 0 },
  visible: {
    x: 0,
    opacity: 1,
    transition: { duration: 0.3 }
  }
};
jsx
const container = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.1,
      when: "beforeChildren"
    }
  }
};

const child = {
  hidden: { x: -20, opacity: 0 },
  visible: {
    x: 0,
    opacity: 1,
    transition: { duration: 0.3 }
  }
};

Best practices

最佳实践

  • ✅ Use variants for reusable, coordinated animations.
  • ✅ Use staggerChildren for list animations.
  • ✅ Use custom prop to pass dynamic values.
  • ✅ Define exit variants for AnimatePresence.
  • ✅ Use when option for parent-child coordination.
  • ✅ 使用 variants 实现可复用、协同的动画。
  • ✅ 使用 staggerChildren 实现列表动画。
  • ✅ 使用 custom 属性传递动态值。
  • ✅ 为AnimatePresence定义 exit 变体。
  • ✅ 使用 when 选项实现父子组件协同。

Do Not

注意事项

  • ❌ Mix motion values and variants incorrectly.
  • ❌ Forget that variant transitions can be overridden.
  • ❌ Use too many variant states (keep to 3-5).
  • ❌ Forget to pass
    custom
    when needed.
  • ❌ 错误混用运动值和变体。
  • ❌ 忽略变体过渡可被覆盖的特性。
  • ❌ 使用过多变体状态(建议控制在3-5个)。
  • ❌ 需要时忘记传递
    custom
    属性。

Learn More

了解更多