Framer Motion: 배너에 자연스러운 UX 더하기

ε( ε ˙³˙)з ○º·2025년 6월 19일

Intro

Framer Motion은 React 환경에서 부드럽고 자연스러운 애니메이션을 손쉽게 구현할 수 있는 라이브러리입니다. 간결한 API와 다양한 기능을 제공하고 있어서 실무에서도 자주 활용하고 있어요.


Framer Motion이란?

Framer Motion은 React를 위한 오픈소스 애니메이션 라이브러리로 아래와 같은 특징을 가지고 있어요.

  • Framer Motion 공식 사이트
  • 간단한 API로 빠르게 애니메이션을 적용할 수 있어요.
  • 자연스러운 전환 효과를 기본으로 제공해서 사용자 경험(UX)을 더 부드럽게 만들어줘요.
  • animate, initial, exit, transition처럼 직관적인 props만으로도 다양한 효과를 만들 수 있어요.
  • Variants, Layout animation, Drag 같은 고급 기능도 제공해요.

🛠️ 기본 사용 방법

Framer Motion은 React 기반에서 동작하는 라이브러리라 먼저 프로젝트에 설치해줘야 해요.

# npm 사용 시
npm install framer-motion

# yarn 사용 시
yarn add framer-motion

설치가 완료되면 import { motion } from 'framer-motion' 형태로 사용할 수 있어요.
Framer Motion을 쓰려면 먼저 컴포넌트를 motion으로 감싸주는 게 기본이에요.

motion.div, motion.button, motion.img처럼 HTML 요소를 motion 요소로 래핑하면 바로 애니메이션을 적용할 수 있어요!

👀 실제 구현된 애니메이션은 아래 이미지를 참고해주세요!
(Google Fonts - Press Start 2P)


  • 슬라이드 업과 페이드 인 조합되어 컴포넌트가 아래에서 위로 자연스럽게 올라오면서 opacity는 0에서 1로 부드럽게 전환되는 애니메이션을 보여줘요.

🔧 자주 사용하는 옵션 정리

Framer Motion을 사용할 때 가장 기본이 되는 props들을 간단히 정리해보았어요.

◻️ initial, animate, exit은 컴포넌트의 상태 변화를 정의할 때 사용합니다.

  • exit을 사용하려면 컴포넌트를 AnimatePresence로 감싸야 정상적으로 동작합니다.

◻️ transitioninitial에서 animate, 또는 exit 상태로 전환될 때 속도, 타이밍, 움직임의 완급감을 제어할 수 있는 옵션입니다.

  • duration 애니메이션이 걸리는 시간 (초 단위)
  • delay 애니메이션 시작 전 지연 시간
  • ease 가속도 곡선
    • easeIn 서서히 시작
    • easeOut 서서히 멈춤
    • linear 균등한 속도
  • easeInOut 천천히 시작해서 천천히 끝남
  • type 애니메이션의 타입 (spring, tween 등)
    • spring 튕기듯 자연스럽게
    • tween 일정 시간 내 부드럽게 전환

Framer Motion에서는 상태(animate, exit 등)에 따라 서로 다른 transition을 줄 수 있어요.
initial.transition은 적용되지 않아요. 애니메이션은 도달하는 상태 기준으로 실행되기 때문이에요.


◻️ variants는 여러 애니메이션 상태를 객체로 미리 정의한 뒤 variants prop으로 넘겨 깔끔하게 관리할 수 있습니다.

  • 여러 컴포넌트에서 동일한 애니메이션 상태를 공유하거나 부모에서 자식까지 일관된 애니메이션 흐름을 제어할 때 유용하게 사용할 수 있어요.

◻️ whileHover, whileTap은 사용자의 인터랙션(hover, 클릭 등)에 반응하는 애니메이션으로 버튼이나 카드 같은 요소에 피드백을 줄 때 자주 사용됩니다.

  • drag는 드래그 가능한 요소를 만들 때 사용하며 dragConstraints는 드래그 가능한 범위를 제한할 때 사용하는 옵션이에요.
  • 실무에서는 드래그 가능한 팝업, 슬라이더 등에서 요소가 화면 밖으로 나가지 않도록 제한할 때 사용할 수 있어요.

◻️ layoutId를 사용하면 동일한 layoutId를 가진 요소들 사이에서 자동으로 애니메이션 전환이 연결됩니다.

  • 위 예제에서는 선택된 탭의 밑줄(underline)에 같은 layoutId를 부여해 탭이 바뀔 때 밑줄이 자연스럽게 이동하는 효과를 구현했습니다. (공식 문서 참고)
  • 리스트 → 상세 보기, 축소된 카드 → 확장된 카드처럼 화면 간 전환이 필요한 경우에 유용하게 활용할 수 있어요.

😎 사용자 경험을 높이는 배너 애니메이션 예제

* 아래 코드는 실제 업무에서 사용했던 구조를 참고해 비즈니스 로직이나 내부 데이터 없이 일반화한 예제입니다.

📢 하단 플로팅 배너로 알림 전달

하단에 고정된 배너는 사용자에게 알림이나 CTA(Call to Action)를 방해 없이 전달할 수 있어 자주 사용되는 방식입니다.
아래에서 위로 부드럽게 슬라이드 업되며 등장하고, 사라질 때도 자연스럽게 퇴장되도록 구현했어요.

  • y: 100 → 0 슬라이드 업 애니메이션으로 컴포넌트가 아래에서 위로 자연스럽게 올라옵니다.
  • delay: 1 값을 주어, 애니메이션이 1초 뒤에 시작되도록 설정했습니다.
  • exit 속성을 함께 사용하면 AnimatePresence와 조합해 퇴장 시 애니메이션도 자연스럽게 처리할 수 있습니다.
  • onAnimationStart는 애니메이션이 시작되는 순간 호출되는 콜백 함수입니다.
    배너가 등장하기 시작하는 타이밍에 특정 상태를 변경하거나, 트래킹 이벤트를 전송하는 용도로 활용할 수 있습니다.
  • onAnimationComplete는 애니메이션이 끝난 직후 호출되며 다음 동작을 연결하거나 UI 상태를 정리할 때 유용하게 사용됩니다.

👀 실제 구현된 애니메이션은 아래 이미지를 참고해주세요!


📢 콘텐츠 중간 배너 자연스럽게 띄우기

콘텐츠 중간에 배치된 배너는 사용자 시선을 자연스럽게 이끌 수 있는 위치입니다. 축소된 상태에서 확대되며 등장하는 애니메이션을 사용하면 흐름을 방해하지 않으면서도 시각적인 리듬을 더하고 주목도를 높일 수 있어요.

  • layout 속성은 요소의 위치나 크기가 변경될 때, 부자연스럽게 점프하지 않고 부드럽게 전환되도록 애니메이션을 적용해줍니다.
  • transformOrigin은 요소에 scale, rotate 같은 transform 효과를 줄 때 기준이 되는 위치를 지정하는 CSS 속성입니다.
    • center: 중심에서 부드럽게 커짐
    • top: 위쪽을 기준으로 펼쳐지듯 등장
    • left bottom: 왼쪽 아래 모서리에서 커짐
  • spring 타입에 함께 사용하는 stiffness, damping, mass 옵션은 애니메이션의 물리적 특성을 조절할 수 있습니다.
    • type – 애니메이션 종류 (spring, tween 등)
    • stiffness – 스프링 강도 (값이 클수록 더 빠르고 단단하게 튕김)
    • damping – 감쇠력 (낮을수록 많이 튕기고, 높을수록 부드럽게 멈춤)
    • mass – 질량 (값이 클수록 더 무겁고 천천히 움직임)
  • layout 속성은 요소의 위치나 크기가 바뀔 때 자연스럽게 전환되는 애니메이션을 적용해줘요.

단순히 배너에 scale-in만 적용해도 애니메이션은 동작하지만 기존 콘텐츠를 자연스럽게 밀어내며 배너가 자리 잡을 수 있도록 배너가 들어갈 공간을 미리 확보한 컨테이너 구조를 추가하여 부드러운 전환 모션을 함께 적용했습니다.

배너가 등장할 공간은 height: 0 → auto 전환을 통해 미리 확보하고 등장 타이밍에는 delay 값을 조정해 흐름에 맞춰 애니메이션이 시작되도록 구성했습니다. 이후 실제 배너는 scaleopacity를 활용해 부드럽게 등장하도록 구현했습니다.

👀 실제 구현된 애니메이션은 아래 이미지를 참고해주세요!


💭 마무리하며

Framer Motion은 진입 장벽이 낮으면서도 세밀하고 자연스러운 애니메이션을 쉽게 구현할 수 있어서 사용자 경험을 살리는 모션 UI 구현에 적합한 도구입니다. 실제로 써보면서 로직과 UI가 분리된 선언형 구조 덕분에 작업도 깔끔했고 적용 과정에서도 만족도가 높았어요! 💪🏻

📚 Reference


이 글은 공식 문서를 기반으로 내용을 정리한 포스팅입니다.
혹시 내용 중 틀린 부분이나 보완할 부분이 있다면 댓글로 남겨주시면 감사하겠습니다. 🙏🏻

profile
차곡차곡 쌓아두기 💭

0개의 댓글