[라이브러리]framer-motion

누리·2023년 5월 28일
0

TIL

목록 보기
5/5
npm i framer-motion

라이브러리를 설치후 애니메이션이 실행될 컴포넌트 내에서 motion을 불러온다.
import { motion } from "framer-motion"

애니메이트 준비하기

1. HTML 태그로 선택하기

framer-motion을 사용하기 위해서는 div등의 HTML 태그를 바로 사용할 수가 없다. 내가 애니메이트 시킬 어떤 요소든지 motion 패키지로부터 나온다는 것을 아래의 예시처럼 사용하여 설명 해주어야한다.
<motion.HTML태그명></motion.HTML태그명>

2. 스타일드컴포넌트로 선택하기

우리가 작성한 스타일드컴포넌트로 바로 컴포넌트에 <motion.Example />등으로 작성하여 애니메이션을 줄 수 없다. 스타일을 작성한 코드로 돌아가 살펴보자.

const Example = styled.div`
  display: flex;
  justify-content: center;
`;

styled.div로 작성이 되어있는 것을 styled(motion.div)로 작성하면 해당 컴포넌트에 애니메이션을 작성할 수 있게 되는 것이다.

const Example = styled(motion.div)`
  //원하는 스타일 작성
  border-radius: 15px;
`

애니메이션 작성하기

1. props 직접 전달

애니메이트 시킬 요소에 animateprop을 전달한다.

<Example animate={{borderRadius: "100px"}} />

motion을 주는 props로는

  • animate (애니메이트 시킬 스타일) : borderRadius, x, y 등
  • transition (원하는 것을 특정시킬 수 있다) : type, delay, duration 등
  • initial (엘리먼트의 초기상태 설정) : scale, opacity, 등 (animate속성에서 바뀌는 값을 지정해주어야함)

다양한 옵션들은 공식문서에서 확인해보자

2.0 Variants 사용하기

props를 직접 전달하는 방법은 복잡한 애니메이션을 작성하기에는 코드의 가독성이 떨어진다.

Variants란?

컴포넌트가 가질 수 있는 미리 정의된 시각적 state이다.
variants를 자바스크립트 오브젝트로 넣을때 초기상태와 최종상태의 값이 필요하다.

  • 초기상태 값 = initial props 값
  • 최종상태 값 = animate props 값

    다른점은 transition값을 최종상태 옵션에 같이 작성한다는 점이다

Variants 사용시의 장점 2가지

  • 컴포넌트 코드의 가독성이 좋아진다.
  • 많은 애니메이션들을 하나로 연결시킬 수 있다.
const variantsExample = {
  start: {scale: 0},
  end: {scale: 1, rotateZ: 360, transition: {type: "spring", delay: 0.5}}
}

스타일을 자바스크립트 오브젝트로 한꺼번에 작성한 후

<Example variants={variantsExample} initial="start" animate="end" />
  • variants props 값으로 미리 작성한 오브젝트 변수를 입력
  • initial props 값으로 작성한 오브젝트의 초기상태로 설정한 옵션명을 입력
  • animate props 값으로 작성한 오브젝트의 최종상태로 설정한 옵션명을 입력

2.1 Variants로 연속적인 애니메이션 만들기

연속적으로 똑같은 애니메이션을 주어야하는 경우에 위의 방식처럼 컴포넌트마다 하나하나 다 입력하지 않아도 된다.

자식컴포넌트에서는 부모컴포넌트의 initial 값과 animate값을 상속한다
따라서 오브젝트 작성떄 부모컴포넌트 애니메이션 네이밍만 똑같이 하면된다

부모 컴포넌트가 자식 컴포넌트의 animation을 제어할 수 있고 연속적으로 일어나는 부분에서 관련된 시간을 알아서 계산도 해준다.

부모컴포넌트 애니메이션에서 아래의 속성 사용해보기

  • delayChildren
  • staggerChildren
// 스타일 작성
const Box = styled(motion.div)`
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  width: 200px;
  height: 200px;
  background-color: rgba(255, 255, 255, 0.2);
  border-radius: 40px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
const Circle = styled(motion.div)`
  place-self: center;
  height: 70px;
  width: 70px;
  border-radius: 35px;
  background-color: white;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;

const boxVariants = {
  start: {
    opacity: 0,
    scale: 0.5,
  },
  end: {
    opacity: 1,
    scale: 1,
    transition: {
      type: "spring",
      duration: 1,
      bounce: 0.6,
      delayChildren: 0.5,
      staggerChildren: 0.2,
    },
  },
};
const circleVariants = {
  start: {
    opacity: 0,
    y: 50,
  },
  end: {
    opacity: 1,
    y: 0,
    transition: { duration: 2, type: "spring", bounce: 0.4 },
  },
};
//컴포넌트 작성
<Box variants={boxVariants} initial="start" animate="end">
  <Circle variants={circleVariants} />
  <Circle variants={circleVariants} />
  <Circle variants={circleVariants} />
  <Circle variants={circleVariants} />
</Box>
profile
프론트엔드 개발자

0개의 댓글