L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

framer-motion

framer-motion

Framer Motion animation library for React. Declarative, physics-based and gesture-aware: variants and orchestration, AnimatePresence, FLIP layout animation, scroll-linked motion, spring configuration and gestures. USE WHEN: user mentions "Framer Motion", "motion.div", "AnimatePresence", "variants", "layout animation", "spring animation", asks about animati…

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: framer-motion description: | Framer Motion animation library for React. Declarative, physics-based and gesture-aware: variants and orchestration, AnimatePresence, FLIP layout animation, scroll-linked motion, spring configuration and gestures.

USE WHEN: user mentions "Framer Motion", "motion.div", "AnimatePresence", "variants", "layout animation", "spring animation", asks about animating a React component, exit animations, drag or gesture handling

DO NOT USE FOR: timeline-based or non-React animation (use gsap), SVG-specific animation (use svg-animation), pure CSS effects (use advanced-css-effects) allowed-tools: Read, Grep, Glob, Write, Edit

Framer Motion Skill

Animation library for React. Declarative, physics-based, gesture-aware.

Install

npm install framer-motion

Core API

APIPurpose
motion.divAnimatable element
animate propTarget state
initial propStarting state
exit propUnmount state (requires AnimatePresence)
variantsNamed animation states, enables orchestration
transitionTiming, easing, spring config
whileHover / whileTap / whileFocusGesture states
dragDrag gesture with constraints
layout / layoutIdFLIP layout animation
AnimatePresenceAnimates unmounting components
useScrollScroll progress values
useTransformMap one motion value to another
useSpringSpring-based motion value
useInViewObserve element entering viewport
useAnimationImperative animation control

Variants & Orchestration

const container = {
  hidden: {},
  visible: { transition: { staggerChildren: 0.08, delayChildren: 0.1 } }
};
const item = {
  hidden: { opacity: 0, y: 24 },
  visible: { opacity: 1, y: 0, transition: { duration: 0.4, ease: "easeOut" } }
};

<motion.ul variants={container} initial="hidden" whileInView="visible" viewport={{ once: true }}>
  {items.map(i => <motion.li key={i} variants={item}>{i}</motion.li>)}
</motion.ul>

AnimatePresence

<AnimatePresence mode="wait">
  {isVisible && (
    <motion.div
      key="unique-key"
      initial={{ opacity: 0, y: 10 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -10 }}
      transition={{ duration: 0.2 }}
    />
  )}
</AnimatePresence>

mode="wait" — exits finish before new element enters. mode="popLayout" — exiting element pops out of layout flow.

Layout Animation (FLIP)

// Automatic smooth repositioning
<motion.div layout />

// Shared element transition across routes/conditions
<motion.div layoutId="card-thumbnail" />  // source
<motion.div layoutId="card-thumbnail" />  // destination — auto-animates

Scroll-linked

const { scrollYProgress } = useScroll({ target: ref, offset: ["start end", "end start"] });
const y = useTransform(scrollYProgress, [0, 1], [0, -100]);
const opacity = useTransform(scrollYProgress, [0, 0.3, 1], [0, 1, 0]);

Spring Config

// Bouncy entrance
transition={{ type: "spring", stiffness: 400, damping: 20 }

// Gentle
transition={{ type: "spring", stiffness: 100, damping: 30 }

// No bounce
transition={{ type: "spring", stiffness: 300, damping: 50 }

Gestures

<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.97 }}
  transition={{ type: "spring", stiffness: 400, damping: 20 }}
>
  Click me
</motion.button>

// Drag with constraints
<motion.div
  drag
  dragConstraints={{ left: -100, right: 100, top: -50, bottom: 50 }}
  dragElastic={0.2}
/>

Imperative Control

const controls = useAnimation();

await controls.start({ opacity: 1, y: 0, transition: { duration: 0.4 } });
controls.stop();

<motion.div animate={controls} initial={{ opacity: 0, y: 20 }} />

Reduced Motion

import { useReducedMotion } from "framer-motion";

function AnimatedCard() {
  const reduced = useReducedMotion();
  return (
    <motion.div
      initial={{ opacity: 0, y: reduced ? 0 : 20 }}
      animate={{ opacity: 1, y: 0 }}
    />
  );
}

Common Patterns

// Stagger list reveal on scroll
// Page transition wrapper
// Accordion with layout animation
// Drag-and-drop with layoutId
// Hero → detail shared element

Pitfalls

  • exit only works inside <AnimatePresence> — wrap the closest conditional parent
  • layout on elements that change children count can cause jumps — use layoutId instead
  • Spring animations ignore duration — use stiffness/damping
  • useScroll without target tracks window scroll
  • Always set viewport={{ once: true }} for entry animations to avoid re-triggering on scroll-up
Skills enregistrées