전에 개발을 할 때는 간단한 애니메이션 (팝업 효과라던지, 뭐 디졸브 라던지...) 들은
대부분 직접 만들어서 구현하곤 했었는데, 최근에 개발하면서 기획자분께서 뿅? 뿅? 하고 튀어나오는
애니메이션을 원하셔서 라이브러리의 힘이 절실했다.
일단 해보겠읍니다! 하고 지른 뒤 ChatGPT나 stackoverflow 형들에게 도움을 요청하면 되겠지 했는데
공식문서만 봐도 간단하게 적용할 수 있는 라이브러리라서 어떻게 적용했는지만 기록해 보려고 한다.
Install
npm install framer-motion
해당 라이브러리는 사용하고자 하는 프로젝트에서 위와 같이 설치를 진행하면 된다.
* 참고 Stack *
프레임워크 : Next.js (ver 14.1.0)
스타일 라이브러리 : sass (1.70.0)
애니메이션 라이브러리 : framer-motion (ver 11.0.5)
적용하기
해당 공식문서에서 보면 이 라이브러리를 적용하는 방법에 대해서 간략하게 작성 되어 있었고,
다양한 예시들을 통해 내가 적용하고자 하는 애니메이션들의 예시를 볼 수 있었다.
import { motion } from "framer-motion";
... 중략 ...
<motion.div>
{변경하고자 하는 요소}
</motion.div>
어쨋든 일단 애니메이션을 사용하려면 framer-motion에서 motion 컴포넌트를 import 하고,
애니메이션을 적용할 요소를 <motion.div> 사이에 넣어준다.
motion 컴포넌트에는 애니메이션에 사용할 수 있는 다양한 property가 있는데
기본적으로 가장 많이 보이는건 4가지 정도가 될 수 있을 것 같다.
<motion.div
initial
animate
transition
exit
></motion.div>
initial : 요소가 맨 처음 마운트 됐을 때의 애니메이션을 지정하고 싶을 때
animate : initial 이후 적용되는 애니메이션
transition : 애니메이션 실행시 부수효과
exit : 요소가 언마운트 될 때의 애니메이션을 지정하고 싶을 때
해당 라이브러리 전체를 뜯어본건 아니지만, 대부분의 자료를 보면 위의 네가지를 사용하는 것 같다.
여기서 다른 프로퍼티도 편리하지만 exit가 개인적으로는 가장 편리한 기능이 아닐까 싶다.
왜냐하면 보통 애니메이션을 지정할 때 어떤 동작에 의해서 요소가 나타날때 지정하는데,
사라질 때 애니메이션을 지정하기는 나타날때 보다 까다롭기 때문에
까다로운 부분을 손쉽게 처리해 준다는 점에서 개인적으로는 좋은 포인트라고 생각했다.
근데 내가 하려는 애니메이션에서는 그닥 필요하지 않은 아이러니가...ㅎㅎ
const CARD_LIST = [
{ id: 1, color: "red" },
{ id: 2, color: "blue" },
{ id: 3, color: "yellow" },
{ id: 4, color: "green" },
{ id: 5, color: "purple" },
{ id: 6, color: "gray" },
];
내가 적용하려 하는 애니메이션의 요소는 동일한 사이즈인데 컬러만 다른 형태다.
그래서 위의 예시처럼 컬러를 지정하고 className을 변경하는 형태로 스타일을 변경하려고 했다.
배열 안의 요소를 나열하는 거라 map을 써야하나? 하고 잠깐 멍청한 생각을 했다가
이게 어떤 버튼에 의해서 카드가 하나의 컬러만 노출이 되어야 하기 때문에 바로 생각을 접었다.
const [cardIndex, setCardIndex] = useState(0);
const changeCard = () => {
cardIndex === CARD_LIST.length
? setCardIndex(0);
: setCardIndex((prev) => prev + 1);
};
retrun (
<>
<motion.div>
<div className={`${css.card} ${css[CARD_LIST[cardIndex].color]}`} />
</motion.div>
<button onClick={changeCard}>카드 변경</button>
</>
)
그래서 changeCard 라는 함수를 이용해서 버튼을 누를 때마다 현재 표시할 index 번호를 변경하고
그 index에 맞는 color 를 변경할 수 있도록 구현해 주었다.
근데 이렇게 구현해도 애니메이션은 적용되지 않았다. 근데 그건 당연하다
어떠한 애니메이션 설정도 해주지 않았기 때문이다.
retrun (
<>
<motion.div
key={CARD_LIST[cardIndex].id}
animate={{
scale: [1, 1.05, 1],
}}
transition={{
duration: 0.2,
ease: "easeInOut",
times: [0, 0.5, 1],
}}
>
<div className={`${css.card} ${css[CARD_LIST[cardIndex].color]}`} />
</motion.div>
<button onClick={changeCard}>카드 변경</button>
</>
)
애니메이션을 적용할 때, 맨 위에서 봤던 공식문서의 예시처럼 특정 효과를 고정해서 지정할 수 있지만
위와 같이 시간에 흐름에 따라서 애니메이션을 동적으로 부여할 수 있는 방법도 있었다.
그래서 나는 scale을 이용해서 확대와 축소 효과를 주었고,
짧은 시간안에 해당 효과가 적용되도록 구현해서 카드가 튀어 오르는 듯한 느낌을 내봤다.
결과
그래서 이런 결과를 보여줄 수 있었다 ㅎㅎ그냥 색이 변경하는 것 보다는 훨씬 역동적인(?) 모습을 보여주고 있는데,내가 작업하고 있는 페이지의 성격과도 잘 맞는 것 같아서 나나 기획자분이나 모두 흡족한 애니메이션이었다 ㅋㅋㅋ
참고 자료
'Develop > librarys' 카테고리의 다른 글
[Saida Lab] Next.js에서 google reCAPTCHA 적용하기 (1) | 2024.03.19 |
---|---|
[Saida Lab] Amplitude 적용하기 (0) | 2024.03.18 |