main-logo

Framer-motion 간단하게 살펴보기

Framer-motion 라이브러리 간단하게 살펴보기

profile
NY
2023년 10월 28일 · 0 분 소요

들어가며

모션 관련하여 작은 작업을 해보던 중 Framer-motion이라는 라이브러리를 접하게 되었고 사용해 보면서 의외로 많은 다양한 기능을 포함하고 있는 React용 애니메이션 라이브러리였습니다. 스타일과 유사하게 사용할 수 있는 부분들이 있어 조금 더 알아보면 좋을 것 같아 정리해 보았습니다.

 

설치 방법

우선 react 선 설치가 필요합니다.

그 후 framer-motion 라이브러리를 설치해 주세요.

npm install framer-motion
또는
yarn add framer-motion

 

몇 가지 사용법(예시)

애니메이션 반영이 필요한 화면에 motion을 import 해온 후 연결할 태그에 motion 컴포넌트를 붙여줍니다.

공식 사이트의 예시를 활용하였습니다.

import { motion } from 'framer-motion';

export const MyComponent = () => (
  <motion.div
    initial={{ opacity: 0, scale: 0.5 }}
    animate={{ opacity: 1, scale: 1 }}
    transition={{ duration: 0.5 }}
  />
)

div 가 아니더라도 button , span , a 등 애니메이션을 입힐 태그라면 어디든 적용 가능합니다.

위의 예시를 보면,

initial, animate, transition 등의 prop을 사용하여 애니메이션을 제어할 수 있는데요

자주 사용하게 될 몇 가지 props를 알아보면

initial 은 애니메이션 시작 시 상태

animate 는 애니메이션 종료 시 상태

transition 은 애니메이션 실행 시 상태를 제어할 수 있고,

추가적으로 exit 는 화면에서 unmount 될 때 실행되는 상태 제어, layout 은 화면에서 레이아웃에 따른 위치와 크기가 변경되는 경우 자연스럽게 이동할 수 있도록 해주고 있습니다.

각 props에 옵션들을 정의해 두고 사용할 수 있는데요.

variants 를 사용하여 동적 제어도 가능하게 해 줍니다.

const [isOpen, setIsOpen] = React.useState(false);

const list = {
    visible: { opacity: 1 },
    hidden: { opacity: 0 },
  };

const items = [1, 2, 3];

const listItem = {
  open: {
    y: 0,
    opacity: 1,
    transition: {
      y: { stiffness: 1000, velocity: -100 },
    },
  },
  closed: {
    y: 50,
    opacity: 0,
    transition: {
      y: { stiffness: 1000 },
    },
  },
};

return (
  <div className="wrapper">
    <motion.button 
      whileHover={{ scale: 1.1, rotate: "2.5deg" }}
      whileTap={{ scale: 0.95, rotate: "-2.5deg" }}
      transition={{ duration: 0.125, ease: "easeInOut", }}
      onClick={()=> setIsOpen(!isOpen)}
    >click</motion.button>
    <motion.ul variants={list}
      initial={false}
      animate={isOpen ? "open" : "closed"}
    >
      {items.map((item, i) => (
        <motion.li
          key={i}
          variants={listItem}
          whileHover={{ scale: 1.1 }}
          whileTap={{ scale: 0.95 }}
          >
          <a className="icon-placeholder">{item}</a>
        </motion.li>
      ))}
    </motion.ul>
  </div>
)

Codepen 에서 확인하기

위의 예시는 단일 값으로 제어하고 있는데요.

 배열을 사용하여 키프레임 형태의 모션도 작업 가능합니다.

아래의 예시처럼 값을 배열 형태로 적용해 주면 배열의 순서대로 실행하게 됩니다.

<motion.div
  className="box"
  initial={{	
    y: 0,
    scale: 0,
    rotate: "0deg"
  }}
  animate={{
    y: [0,100,-100,-100,0],
    scale: [1, 2, 2, 1, 1],
    rotate: [0, 0, 180, 180, 0],
    borderRadius: ["0%", "0%", "50%", "50%", "0%"],
  }}
  transition={{
    duration: 2,
    ease: "easeInOut",
    times: [0, 0.2, 0.5, 0.8, 1],
    repeat: Infinity,
    repeatDelay: 1,
  }}
/>

Codepen 에서 확인하기

해당 라이브러리는 간단한 제스처(마우스 hover, click 등)와 드래그도 간단하게 반영 가능하도록 옵션을 제공하고 있습니다.

// drag, hover 예시
<motion.div
  className="box"
  whileHover={{ scale: 1.2 }}
  whileTap={{ scale: 1.1 }}
  drag
  dragConstraints={{ top: -100, left: -100, right: 100, bottom: 100 }}
/>

drag 의 경우 x, y 축을 지정할 수 있으며, 선언하지 않으면 상하좌우 드래그가 가능합니다.

drag="x" 로 축을 지정하고, 움직일 수 있는 영역을 전체가 아닌 일정 영역을 설정할 경우 dragConstraints 옵션에 left, right 값을 지정해 주면 됩니다.

Codepen 에서 확인하기

이 외에도 다양한 모션과 스크롤 애니메이션, 숫자(텍스트) 카운트 모션이나 토글 애니메이션 등 간단하게 사용할 수 있는 예제들이 많았지만 다 설명하기에 너무 많은 옵션들이 있어 공식 사이트를 하단 참고 문서에 링크 추가해 두었으니 구현 시 필요한 부분이 있는지 확인해 보시면 좋을 것 같습니다.

 

마치며

간단한 테스트 작업을 진행해 보면서 사용법이 스타일과 유사하여 조금 더 친숙하게 접근할 수 있겠다는 생각이 들어 framer-motion 라이브러리를 소개해보았는데요.

극히 일부의 prop 들을 소개하였지만 프로젝트를 진행하면서 해당 라이브러리를 응용해서 사용해보고 싶은 부분들이 있을 것 같아 좀 더 자세히 봐두는 것도 좋을 것 같다는 생각이 들었습니다.

다른 분들도 시간 되실 때 한번 경험해 보시는 것도 나쁘지 않을 것 같네요.

부족한 글 읽어주셔서 감사합니다.😊

그럼 안녕히…👋  -To be continued-

 

참고 문서