BLOG

Next.jsでページ遷移アニメーションを実装する

5/17/2023

こんにちは、ZOOANです。
Next.js 13.4の試用を兼ねて、ページ遷移アニメーションを実装してみました。

目次

デモ

「ここをクリック」という部分をクリックするとページ遷移します。

DEMO

ディレクトリ構成

ディレクトリ構成は以下の通りです。

├─ app
│  │  component-link.tsx
│  │  client-home.tsx
│  │  page.tsx
│  │  
│  └─ test
│          client-test.tsx
│          page.tsx

内容

/app/page.tsx, /app/test/page.tsx

ページファイルなので割愛します。

/app/component-link.tsx

クリック時にアニメーション処理を実行するコンポーネントです。
CSSでtransitionを設定しています。

'use client'

import { useEffect } from 'react'
import { useRouter } from 'next/navigation'
import Link from 'next/link'

type Props = {
  href: string,
  children: React.ReactNode,
}

export const useReset = () => {
  const router = useRouter()

  useEffect(() => {
    const body = document.querySelector('body')!
    body.classList.remove('page-transition-animation')
  }, [router])
}

export default function LinkComponent(props: Props) {
  const router = useRouter()
  const clickEventHandler = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
    e.preventDefault()
    const body = document.querySelector('body')!
    body.classList.add('page-transition-animation')
    setTimeout(() => {
      router.push(props.href)
    }, 1000)
  }

  return (
    <Link href={props.href} onClick={clickEventHandler}>{props.children}</Link>
  )
}

/app/client-home.tsx

component-link.tsxをimportしてtestページへのリンクを設置します。

'use client'

import CmLink from '@/app/component-link'

export default function ClientHome() {
  return (
    <>
      <div className="h-screen flex items-center justify-center">
        <p>Top Page</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>1</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <CmLink href="/test">2!ここをクリック!</CmLink>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>3</p>
      </div>
    </>
  )
}

/app/test/client-test.tsx

component-link.tsxのカスタムフックを呼び出して、マウント時にアニメーション処理をリセットします。

'use client'

import { useReset } from '@/app/component-link'

export default function ClientTest() {
  useReset()

  return (
    <>
      <div className="h-screen flex items-center justify-center">
        <p>Test Page</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>1</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>2</p>
      </div>
      <div className="h-screen flex items-center justify-center">
        <p>3</p>
      </div>
    </>
  )
}

以上です。
ちょっとだけでもReactとNext.jsがわかってくると開発が楽しくなってきますね。まだまだわからないことだらけなので、引き続きフロントエンド周りの学習を続けたいと思います。

参考