![[Next.js] Framer Motion 화면 전환 애니메이션 적용 (feat. Page Router)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj62xb%2FbtsIuopP31o%2FStfeLI7xc5Y73aGQ9U0LR1%2Fimg.png)
시작하며...
나는 Framer Motion 중독자다... 애니메이션을 통해 사용자의 경험성을 늘릴 수 있고 라이브러리를 사용하여 간편하게 애니메이션을 구현할 수 있기 때문이다. Framer Motion 짱!! 🙌 그런데 Next.js 에서 화면 전환 애니메이션을 적용하면서 React 와는 조금 달라 글을 작성하게 되었다.
이전에 Framer Motion 에 관한 내용을 쓴 적이 있다. https://jjang-j.tistory.com/95
[React] Framer motion 애니메이션 적용 - 버튼, 모달, 스크롤, 화면전환
시작하기 앞서...이번에 프로젝트를 하면서 framer motion 을 활용하여 버튼, 모달, 스크롤, 화면 전환 애니메이션을 적용하였다.그래서 사용 방법에 대해 자세하게 정리하기 위해 글을 작성하게 되
jjang-j.tistory.com
화면 전환 애니메이션 적용
AnimatePresence 감싸기
Next.js Page Router 의 _app.tsx
에서 AnimatePresence 를 감싸주고, mode 는 wait 으로 설정하였다.
AnimatePresence 는 컴포넌트가 마운트되거나 언마운트 될 때 애니메이션을 적용할 때 사용되기 때문에 주로 페이지 전환이나 표시/숨김 등에 애니메이션을 적용할 때 사용된다.
그리고 여기에 mode 로 sync, wait, popLayout 속성을 설정할 수 있다.
- sync - 기본모드, enter/exit 동시에 실행
- wait - exit 완료된 후, enter 시작
- popLayout - exit 실행된 후, 레이아웃이 변경되고 새 컴포넌트가 enter 시작
먼저 sync 모드는 애니메이션이 겹쳐서 잘 적용되지 않는 것처럼 보였고, popLayout 은 전환속도도 빠르고 부드럽게 전환되지만 레이아웃이 잔상처럼 남는 것이 보여서 그나마 괜찮아 보이는 wait 으로 모드를 설정하였다.
import { AnimatePresence, motion } from 'framer-motion';
const App = ({ Component, pageProps, router }: AppProps) => {
return (
<>
<TopNavigationBar />
<AnimatePresence mode="wait">
<Wrapper>
<Component {...pageProps} />
</Wrapper>
</AnimatePresence>
</>
);
};
export default App;
AnimatePresence | Framer for Developers
Animate components when they're removed from the React tree.
www.framer.com
애니메이션 적용
AnimatePresence 하위에 motion.div 를 통해 애니메이션을 적용할 수 있다.
- initial - 컴포넌트가 처음 렌더링될 때 상태
- animate - 컴포넌트 활성화될 때 최종 상태
- exit - 컴포넌트가 제거될 때 상태
- transition - 애니메이션 지속 시간
그래서 페이지가 전환될 때마다 컴포넌트가 페이드인/아웃 되면서 좌우로 슬라이드 되는 애니메이션을 적용하였다.
return (
<>
<TopNavigationBar />
<AnimatePresence mode="wait">
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
transition={{ duration: 0.5 }}
>
<Wrapper>
<Component {...pageProps} />
</Wrapper>
</motion.div>
</AnimatePresence>
</>
);
key 값 적용
여기서 끝이 아니다! Next.js 에서는 페이지 경로가 바뀔 때마다 페이지를 고유하게 식별해서 페이지 전환 시 새로운 애니메이션을 적용하기 위해 key 값을 적용해야 한다. 즉 경로가 바뀔 때마다 key 값이 바뀌어 애니메이션이 실행되는 것이다. 그래서 현재 페이지의 전체 경로를 가져오는 router.asPath
를 사용하였다.
return (
<>
<TopNavigationBar />
<AnimatePresence mode="wait">
<motion.div
key={router.asPath}
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
transition={{ duration: 0.5 }}
>
<Wrapper>
<Component {...pageProps} />
</Wrapper>
</motion.div>
</AnimatePresence>
</>
);
결과
다음과 같은 결과가 나타난다.

다른 애니메이션
애니메이션 전환 효과로 스프링이 튀기는 것처럼 물리엔진 기반을 활용해서 구현할 수 있다.
return (
<>
<TopNavigationBar />
<AnimatePresence mode="wait">
<motion.div
key={router.asPath}
initial={{ opacity: 0, rotate: 90 }}
animate={{ opacity: 1, rotate: 0 }}
exit={{ opacity: 0, rotate: -90 }}
transition={{
type: 'spring',
stiffness: 300, // 스프링 강도
damping: 15, // 스프링 감쇠
mass: 1, // 스프링 질량
duration: 0.5, // 지속 시간
}}
>
<Wrapper>
<Component {...pageProps} />
</Wrapper>
</motion.div>
</AnimatePresence>
</>
);
좀 정신없지만 😅 다양한 애니메이션을 적용할 수 있다!

마치며...
Framer motion 을 사용해서 Next.js Page Router 의 화면 전환 애니메이션을 적용해 봤다. 짧은 코드로 사용자 경험성도 늘릴 수 있어 정말 좋은 것 같다 😊
'💜 리액트 > Next.js' 카테고리의 다른 글
[Next.js] Server Sider Rendering 특정 사용자 접근 제한 (feat. App Router) (0) | 2024.08.11 |
---|---|
[Next.js] 메타태그, 오픈그래프 컴포넌트 SEO 향상 (feat. Page Router) (0) | 2024.07.12 |
[Next.js] Zustand persist 사용하기 (feat. Hydration 에러 해결) (1) | 2024.07.01 |
[Next.js] create-next-app 없이 프로젝트 생성하기 (0) | 2024.06.21 |
[Next.js] SVG 컴포넌트 사용하는 방법 (React 보다 짱편함!) (0) | 2024.06.04 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!