Next.js でReactのアニメーションライブラリであるframer-motionを使ったので、メモがてら記事にしたいと思います。
当方初投稿なので至らない点もあるかと思いますが、温かい目で見てもらえればと思います。
はじめに
Framer MotionとはReactで使用できるアニメーションライブラリです。純粋にアニメーションを実装しようとするとかなり複雑なものになってしまいますが、専用のコンポーネントを使うことで手軽にプログラムに組み込めるようになっています。
react-router-dom と組み合わせたものが多いですが、Next.js との相性も良さそうです。
前提
- Next.js v10.1.3
- TypeScript
- framer-motion v4.1.16
framer-motionのインストール
npm でインストールできます。
npm install framer-motion
コード
_App.tsx
import React from "react";
import type { AppProps } from "next/app";
import { AnimatePresence } from "framer-motion";
function MyApp({ Component, pageProps, router }: AppProps) {
return (
<div>
<AnimatePresence exitBeforeEnter>
<Component {...pageProps} key={router.route} />
</AnimatePresence>
</div>
);
}
export default MyApp;
Next.js はファイル名を元にルーティングされるのでルーターの細かい設定は要りません。(楽!)
<Component>
の中身がルーティングによって変わるので、その上を<AnimatePresence>
で囲います。これはコンポーネントがアンマウントされた時のアニメーションを有効にするものです。
exitBeforeEnter
のPropはコンポーネントがアンマウントされるのを待ってから次のコンポーネントに移るものです。これがないと遷移元のアンマウントと遷移先のマウントのアニメーションが同時に発火してしまいます。
子要素である<Component>
には必ずkey
を追加してください。値はrouter.routeが一意な値を返してくれます。
(任意のページ).tsx
import React from "react";
import { motion } from "framer-motion";
export default function Home() {
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ ease: "easeOut", duration: 1 }}
>
<...>
</motion.div>
各ページのコードでは<motion>
コンポーネントでアニメーションを実装します。アニメーションの動きは以下のようになります。
- マウント時: initial → animate
- アンマウント時: animate → exit
transitionではアニメーションの種類(ease)や時間(duration)などを記述します。
framer-motionの機能についてはまだ把握しきれていない部分が多いので、省略します。かなり多彩なアニメーションを作ることができるみたいなので、是非こちらを参照してみてください。
まとめ
Next.js(React)でアニメーションを実装する時にはとても有用だなと感じました。是非導入を検討してみてはいかがでしょうか。
拙いながらも、アウトプットが大事だと思い記事を書いてみました。まだまだ足りないところばかりですが、今後も記事を投稿してみようと思うのでよろしくお願いいたします!