React

[React] Framer Motion(1) 애니메이션 효과

cob 2022. 9. 29. 13:53

 

ReactJS 애니메이션 라이브러리

 

 

* 공식 문서 *
https://www.framer.com/developers/

 

 


1.  라이브러리 설치

npm install framer-motion

 

 

 


2.  기본 사용 방법

import { motion } from "framer-motion";

export const MyComponent = ({ isVisible }) => (
	<motion.div animate={{ opacity: isVisible ? 1:0 }} />
)

 

  • 애니메이션 효과를 주기 위해서는 element가 motion 패키지에서 나와야 한다.

 

 

 


3.  Styled 컴포넌트를 활용하기 

Style-Components 란?
https://cocococo.tistory.com/8
const Box = styled(motion.div)`
  width: 200px;
  height: 200px;
  background-color: white;
  border-radius: 15px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;

function App() {
  return (
      <Box transition={{delay:3}} animate={{ borderRadius: "100px" }} />
  );
  • animate : 애니메이션이 실행되고 끝났을 때 최종 스타일
  • transition : 원하는 실행 조건을 특정시킬 수 있다.
    ex ) delay:3 (3초 뒤에 실행), duration:3  (3초 동안 실행)

 

 

3-1) 애니메이션 효과 예

* transition 옵션 참조 문서 *
https://www.framer.com/docs/transition
//  나타나는 효과 (scale: 0(hide)  scale: 1(show))  
<Box initial={{ scale: 0 }} animate={{ scale: 1 }}  />

// 회전 효과 (rotateZ: 360  360도 회전)
<Box initial={{ scale: 0 }} animate={{ scale: 1, rotateZ: 360 }} />

// 튕김 효과 적용
<Box transition={{ type: "spring" }} initial={{ scale: 0 }} animate={{ scale: 1, rotateZ: 360 }} />

// 뻣뻣한 spring 적용 (stiffness)
<Box transition={{ type: "spring", stiffness: 10 }} initial={{ scale: 0 }} animate={{ scale: 1, rotateZ: 360 }} />

// 반동력 spring 적용 (damping)
<Box transition={{ type: "spring", damping: 1 }} initial={{ scale: 0 }} animate={{ scale: 1, rotateZ: 360 }} />

// 튕김 효과 해제(선형적 진행)
<Box transition={{ type: "tween" }} initial={{ scale: 0 }} animate={{ scale: 1, rotateZ: 360 }} />

// 바운스 효과
<Box transition={{ type: "spring", bounce: 0.25 }} initial={{ scale: 0 }} animate={{ scale: 1, rotateZ: 360 }} />
  • 애니메이션은 initial(초기 값)로부터 animate(최종 값)된다.
  • tween : 모든 애니메이션은 spring이 기본적으로 적용되어 있기 때문에 튕김 효과가 생긴다. tween을 적용하면 선형적으로 진행된다.
  • spring : 현실 세계의 물리법칙(힘, 탄력성, 경직 등)을 적용한다. 

 

 

 

 


4. Variants 사용하기

Variants 란?
애니메이션의 단계로 initial(초기 상태), finish(최종 상태), showing(보이는 상태), hidden(숨긴 상태) 등
원하는 무엇이든 될 수 있다.

장점
- 코드를 깔끔하게 해 준다.
- 많은 애니메이션들을 하나로 연결시켜준다.
/* 기존 */
<Box
	transition={{ type: "spring", delay: 0.5 }}
	initial={{ scale: 0 }}
	animate={{ scale: 1, rotateZ: 360 }}
/>


/* Variants 적용 */
const variants = {
  // variants 이름은 마음대로 설정 가능
  start: { scale: 0 },
  end: { scale: 1, rotateZ: 360, transition:{ type: "spring", delay: 0.5} },
};

<Box variants={variants} initial="start" animate="end" />
  • variants 변수를 만들어 prop 값을 세팅해 여러 가지 애니메이션 효과를 적용할 수 있다.
  • initial, animate : variants 변수에 작성한 prop이름을 동일하게 명시해 준다.

 

 

4-1) 애니메이션 효과 상속

자식이 기본 값으로 어떤 설정도 없을 때 부모 컴포넌트가 가지고 있는 variants와 initial, animate 등
variants를 기본 동작으로 상속받는다.
const boxVariants = {
  start: { opacity: 0, scale: 0.5 },
  end: {
    opacity: 1,
    scale: 1,
    transition: {
      type: "spring",
      duration: 0.5,
      bounce: 0.5,
    },
  },
};
const circleVariants = {
  start: { opacity: 0, y: 10 },
  end: {
    opacity: 1,
    y: 0,
  },
};

function App() {
  return (
    <Wrapper>
      <Box variants={boxVariants} initial="start" animate="end">
        <Circle variants={circleVariants} />
        <Circle variants={circleVariants} />
        <Circle variants={circleVariants} />
        <Circle variants={circleVariants} />
      </Box>
    </Wrapper>
  );
}

export default App;
  • 부모의 variant가 상속되고, 부모의 motion효과를 그대로 적용하면서 새로운 animate를 추가하기 위해 자식 역시 variants를 만들어 준다
  • 컴포넌트에 같은 variants를 넣어주기만 하면 똑같이 작동한다.

 

 

4-2) staggerChildren

여러 개의 자식이 있을 경우 개별적으로 효과 적용하는 방법
const boxVariants = {
  start: { opacity: 0, scale: 0.5 },
  end: {
	   ...
      
      delayChildren: 0.5,   // 자식 컴포넌트 delay 적용
      staggerChildren: 0.5, // 0.5*2 ...
    },
  },
};
  • delayChildren : 모든 자식 컴포넌트에 delay 적용
  • staggerChildren : 첫 번째 자식에 n초 delay를 주고, 이후 n*1, n*2... 씩 증가한 delay 적용한다.

 

 


5. useAnimation Hook ( 코드를 통한 애니메이션 적용 ) 

여러 애니메이션들을 동시에 실행시키고 싶을 때 유용하다.
import { useAnimation } from "framer-motion";

...

const inputAnimation = useAnimation();
  // toggleSearch이 호출되면 애니메이션도 실행된다.
  const toggleSearch = () => {
    if (searchOpen) {
      /* 코드를 통한 애니메이션 효과 적용 */
      // close 애니메이션
      inputAnimation.start({ scaleX: 0 });
    } else {
      // open  애니메이션
      inputAnimation.start({ scaleX: 1 });
    }
    setSearchOpen((prev) => !prev);
  };

...

<Input
	transition={{ type: "linear" }}
	initial={{ scaleX: 0 }}
	animate={inputAnimation}
	placeholder="Search for movie or tv show..."
/>
  • animate 옵션에 useAnimation을 준다.
  • start : 애니메이션 실행
  • stop: 애니메이션 종료
반응형