npm i framer-motion
라이브러리를 설치후 애니메이션이 실행될 컴포넌트 내에서 motion을 불러온다.
import { motion } from "framer-motion"
framer-motion을 사용하기 위해서는 div
등의 HTML 태그를 바로 사용할 수가 없다. 내가 애니메이트 시킬 어떤 요소든지 motion 패키지로부터 나온다는 것을 아래의 예시처럼 사용하여 설명 해주어야한다.
<motion.HTML태그명></motion.HTML태그명>
우리가 작성한 스타일드컴포넌트로 바로 컴포넌트에 <motion.Example />
등으로 작성하여 애니메이션을 줄 수 없다. 스타일을 작성한 코드로 돌아가 살펴보자.
const Example = styled.div`
display: flex;
justify-content: center;
`;
의 styled.div
로 작성이 되어있는 것을 styled(motion.div)
로 작성하면 해당 컴포넌트에 애니메이션을 작성할 수 있게 되는 것이다.
const Example = styled(motion.div)`
//원하는 스타일 작성
border-radius: 15px;
`
애니메이트 시킬 요소에 animate
prop을 전달한다.
<Example animate={{borderRadius: "100px"}} />
motion을 주는 props로는
- animate (애니메이트 시킬 스타일) : borderRadius, x, y 등
- transition (원하는 것을 특정시킬 수 있다) : type, delay, duration 등
- initial (엘리먼트의 초기상태 설정) : scale, opacity, 등 (animate속성에서 바뀌는 값을 지정해주어야함)
다양한 옵션들은 공식문서에서 확인해보자
props를 직접 전달하는 방법은 복잡한 애니메이션을 작성하기에는 코드의 가독성이 떨어진다.
컴포넌트가 가질 수 있는 미리 정의된 시각적 state이다.
variants를 자바스크립트 오브젝트로 넣을때 초기상태와 최종상태의 값이 필요하다.
다른점은 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" />
연속적으로 똑같은 애니메이션을 주어야하는 경우에 위의 방식처럼 컴포넌트마다 하나하나 다 입력하지 않아도 된다.
자식컴포넌트에서는 부모컴포넌트의 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>