Next.js 14 + Framer Motion でページ遷移アニメーションを実装する方法
当サイトはポートフォリオを兼ねたNext.jsの習作サイトとして作成しています。
ページ遷移を少しリッチにしたく、良いアニメーションのライブラリを探していたところ「Framer Motion」が良さそうだったので導入することにしました。
ところがYouTubeやGoogle検索、果てはGithub Copilotに頼っても上手く動かなかったので、英語版の動画を漁ったところ、きちんと動くように実装することができたので書き残します。
実装環境
- Next.js 14
- TypeScript
- Framer Motion
挙動はローカル環境で確認。CSSにTailwind、ヘッドレスCMSにSanityを使用していますがおそらく関係ないのでリストからは除外しています。
作業手順
1. Framer Motion のインストール
※すでにインストール済の場合はスキップします
まずはターミナルにコマンドを入力して「Framer Motion」をインストールします。
npm install framer-motion
または
yarn add framer-motion
インストールが完了したら次へ!
2. template.tsxの作成
次に、プロジェクトのディレクトリ./app
内にtemplate.tsx
ファイルを作成します。このファイルに、ページ遷移時のアニメーションを定義するコンポーネントを書いていきます。
このtemplate.tsx
は、役割としてはlayout.tsx
と類似しています。しかし、layout.tsxに記述した内容はページを遷移しても再レンダリングされません。「最初はアニメーションが動いたけど、他のページを開いてもアニメーションが動作しない」という現象が起こり、=ページ遷移アニメーションの実装には適さない。ということのようです。(参考にした動画の解説と自分で調べた内容で導き出した答えなので、間違っていたらご指摘ください)
3. PageTransitionコンポーネントの実装
template.tsx
にコードを記述していきます。
'use client'
import { ReactNode } from 'react';
import { motion } from 'framer-motion';
interface PageTransitionProps {
children: ReactNode;
}
export default function PageTransition({ children }: PageTransitionProps) {
return (
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ ease: 'easeInOut', duration: 0.75 }}
>
{children}
</motion.div>
);
}
それぞれざっくりと何をしているのか説明
'use client'
ディレクティブは、このコンポーネントがクライアントサイドでレンダリングされることを示します。motion.div
は、Framer Motionが提供するアニメーション可能なdiv
要素です。initial
プロパティは、アニメーションの開始状態を定義します(この場合、少し下にずれて透明)。animate
プロパティは、アニメーションの終了状態を定義します(元の位置に戻り、完全に不透明になる)。transition
プロパティは、アニメーションのタイミングと動きを制御します。{children}
にpage.tsx
の内容が挿入されます。
また、TypeScriptを使うならchildrenに型を指定しなさーい!というエラーでお叱りを受けたので本ファイルで記述しています。
環境によっては不要な方もいると思います。
4. ふわっと動くページ遷移アニメーションが実装!
キャプチャー撮ったけどコンテンツの中身を入れていないからよくわからない。
きちんと中身を入れたら撮り直そうと思います…。
参考
How to Add Page Transitions in NextJs 14
シンプルで要点を絞った、分かりやすい素敵な動画でした。ありがとうございます!英語が聞き取れなくても、手順の参考になりますので実際に作業を見ながら進めたい方は見てみてください。