LoginSignup
7
1

More than 1 year has passed since last update.

Next.jsでアニメーションパッケージ(ScrollReveal)を使用する際の注意点

Posted at

はじめに

Next.jsを使用しているプロジェクトにアニメーションを使用する機会があり、そこで、Next.jsの概念周りで理解力不足ではまった点があるので、記録として残しておきます。

Next.js(ssgやssr)でアニメーションをする際の注意点

自分がハマったのが、ScrollRevealというパッケージを使用して、スクロールすると対象の要素がふわっと浮き上がるアニメーションを実装しようとした時です。
https://scrollrevealjs.org/

//jacascript インストール
npm i (yarn add) scrollreveal
//typescriptインストール
npm i (yarn add) @types/scrollreveal

まず、すのReactでのコードを見ていきます。

import { useRef, useEffect } from "react";
import { NextPage } from "next";
// ビルド時にimportしている
import scrollReveal from "scrollreveal";

type Props = {
  move: string;
  delay: number
  className?: string
}

const ScrollReveal: NextPage<Props> = ({
  children,
  move,
  delay,
  className
}) => {
  const sectionRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    async function animate() {
      if (sectionRef.current) {
        //ここに注目
        scrollReveal().reveal(sectionRef.current, {
          delay: delay,
          opacity: 0,
          origin: move,
          distance: "20px",
          viewFactor: 0.2
        })
      }
    }
    animate()
  }, [sectionRef])
  return <div className={`${className}`} ref={sectionRef}>{children}</div>
};
export default ScrollReveal;

このように、記述できます。

しかし、Next.jsでSSG(静的サイトジェネレーション)、SSR(サーバーサイトジェネレーション)を用いた開発を行う際、yurn build もしくは npm run buildする際に document is not defined というエラーが出てきます。

エラーの原因

ScrollRevealパッケージをimportする際、パソコンの情報(windowの横、縦幅など)が必要なんですが、ビルド時には、それらの情報は存在しないのでエラーが出ます。

解決策

ビルド時にScrollRevealをimportせずに、ユーザーがパソコンでサイトを開いたタイミングでScrollRevealをimportする。

具体的な解決策

まず、Next.jsには Dynamic import というパッケージのimport方法があるのでこの技術を使用してエラー回避します。

Dynamic Import

これは、動的にパッケージをimportする技術です。(動的というとわかりにくいので、ユーザーがサイトを開いたタイミングというふうに認識しています。間違ってたらごめんなさい。。。)
つまり、ビルド時、サーバーサイドではScrollRevealパッケージをimportせずに、ユーザーがサイトを訪れたタイミングで初めてimportし、document is not definedを回避するということです。

Next.jsでのコード

import { useRef, useEffect } from "react";
import { NextPage } from "next";
//importしていない


type Props = {
  move: string;
  delay: number
  className?: string
}

const ScrollReveal: NextPage<Props> = ({
  children,
  move,
  delay,
  className
}) => {
  const sectionRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    async function animate() {
      if (sectionRef.current) {
        //Dynamic import
        const sr = (await import("scrollreveal")).default
        sr().reveal(sectionRef.current, {
          delay: delay,
          opacity: 0,
          origin: move,
          distance: "20px",
          viewFactor: 0.2
        })
      }
    }
    animate()
  }, [sectionRef])
  return <div className={`${className}`} ref={sectionRef}>{children}</div>;
};
export default ScrollReveal;

このように記述を変更すれば、エラー回避できます!!

まとめ

Next.jsでは、概念から理解しないとハマるところではハマるので難しいです。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1