본문 바로가기
궁금한 것

Framer Motion

by 쪼꼬에몽 2025. 12. 28.

Motion — JavaScript & React animation library

 

Motion — JavaScript & React animation library

Motion (prev Framer Motion) is a fast, production-grade web animation library for React, JavaScript and Vue. Build smooth UI animations with examples, tutorials, and a tiny footprint.

motion.dev

 

React에서 애니메이션을 상태 변화처럼 다룰 수 있게 해주는 애니메이션 라이브러리.

CSS 애니메이션이나 keyframes처럼 언제 시작할지 계산하는 방식이 아니라,

컴포넌트의 상태가 바뀌면 자연스럽게 애니메이션이 따라오는 선언형 방식.

<motion.div
  initial={{ opacity: 0 }}
  animate={{ opacity: 1 }}
/>

 

opacity가 0에서 1로 변화.

React state처럼 선언만 하면 자동으로 transition.

 

HTML 태그 앞에 motion. 을 붙이면 애니메이션 가능

import { motion } from "framer-motion";

<motion.div />
<motion.button />
<motion.ul />

 

가장 중요한 props 4개

1. initial

처음 렌더링 상태

initial={{ opacity: 0, y: 20 }}

 

2. animate

목표 상태

animate= {{ opacity: 1, y: 0 }}

 

3. exit

언마운트될 때 상태

AnimatePresence와 함께 사용

exit={{ opacity: 0, y: -20 }}

 

4. transition

어떻게 움직일지

transition={{
  duration: 0.4,
  ease: "easeOut",
}}

 

AnimatePresence (등장 / 퇴장 애니메이션)

React는 기본적으로 컴포넌트가 사라질 때 애니메이션을 못 줌.

Framer Motion은 AnimatePresence로 해결.

import { AnimatePresence, motion } from "framer-motion";

<AnimatePresence>
  {isOpen && (
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
    />
  )}
</AnimatePresence>

 

Variants (대규모 애니메이션의 핵심)

상태 이름 기반 애니메이션

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

<motion.div
  variants={boxVariants}
  initial="hidden"
  animate="visible"
/>

 

애니메이션 재사용

부모 -> 자식 동기화 가능

코드 가독성 상승

부모-자식 애니메이션 연동 (Stagger)

const container = {
  hidden: {},
  visible: {
    transition: {
      staggerChildren: 0.1,
    },
  },
};

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

<motion.ul variants={container} initial="hidden" animate="visible">
  <motion.li variants={item} />
  <motion.li variants={item} />
</motion.ul>

 

리스트 등장, 카드 UI, 메뉴 애니메이션.

Gesture 애니메이션 (Framer Motion 강점)

Hover / Tap

<motion.button
  whilteHover={{ scale: 1.05 }}
  whilteTap={{ scale: 0.95 }}
>
  Click
</motion.button>

 

Drag

<motion.div
  drag
  dragConstraints={{ left: 0, right: 100 }}
/>

 

드래그 카드, 슬라이더, 스와이프

Layout 애니메이션

DOM 구조 변경 -> 자동 애니메이션

<motion.div layout />

<motion.ul layout>
  {items.map(item => (
    <motion.li key={item.id} layout />
  ))}
</motion.ul>

 

정렬 변경, 필터 변경, 리스트 추가/삭제.

CSS로는 거의 불가능한 영역 가능.

페이지 전환 애니메이션

<AnimatePresence mode="wait">
  <motion.div
    key={router.pathname}
    initial={{ opacity: 0 }}
    animate={{ opacity: 1 }}
    exit={{ opacity: 0 }}
  />
</AnimatePresence>

 

SPA 감성, 부드러운 UX.

성능

  • requestAnimationFrame 기반
  • GPU 친화적
  • layout 애니메이션도 최적화

주의

  • 너무 많은 motion 컴포넌트
  • 무분별한 layout 애니메이션
  • 긴 리스트 + 동시에 애니메이션

호버 시 CSS vs Framer Motion

Framer Motion (핵심 인터랙션)

<motion.button whileTap={{ scale: 0.95 }} />
  • 이 호버가 사용자 행동을 유도하면
  • hover 중 상태가 바뀔 수 있으면
  • hover + click + focus 연결되면
  • 정보가 늘어나거나 의미가 바뀌면 

CSS (기본 hover)

.button {
  transition: background-color 0.2s;
}
  • 단순 피드백이면
  • 시각적 강조만 있으면

 

 

'궁금한 것' 카테고리의 다른 글

stopPropagation  (0) 2025.12.29
import { } 유무 차이  (0) 2025.12.26
해당 섹션에 도착 시 nav에 이벤트 주기 scroll spy  (0) 2025.12.25
nav 클릭 시 원하는 섹션으로 스크롤 이동 Anchor Scroll  (0) 2025.12.25
::after  (0) 2025.12.23