現在WEB制作のコーダー3年目。フロントエンドエンジニアになろうと思い、React学習がてらにデモサイトを制作しました。
初めてReactでサイト制作をしたのですが、そのときにGSAPでローディングアニメーションを実装したので、そのときの備忘録を残していきます。
デモサイトについて
初めてのReactでの制作。Next.jsとMicroCMSを使いました。
コーダーとして就職する前にポートフォリオとして制作した静的デモサイトがあるのですが、今回のデモ制作はそのサイトのデザインを流用したものです。
Next.jsで作りつつ、CSSは当時のものを再利用。フロントエンドだけ作り、MicroCMSをAPI接続することで管理画面からの更新ができるようにしました。
つまり実務未経験時代の自分が作った静的サイトを、モダンJSを使って動的化したということです。時代の流れと自分自身の変化を感じます。
実装したアニメーション
ローディング時にファーストビューの視界が中央から左右に向かって広がるようなアニメーションにしました。

jQueryでやっていたようなことをReactコンポーネント上でやってみた、という感じです。
使用フレームワークとライブラリ
使用ソースコード
"use client";
import { useEffect, useRef } from "react";
import gsap from "gsap";
import styles from "./index.module.css";
export const Loader = () => {
const leftRef = useRef<HTMLDivElement>(null);
const rightRef = useRef<HTMLDivElement>(null);
useEffect(() => {
gsap.to([leftRef.current, rightRef.current], {
duration: 1,
width: "0%",
ease: "power2.inOut",
delay: 0.5,
});
}, []);
return (
<div className={styles.loader}>
<div ref={leftRef} className={styles.left} />
<div ref={rightRef} className={styles.right} />
</div>
);
};
上記はローディング部分をモジュール化したtsxファイルのソースコードです。
Loaderというコンポーネントがexportされています。
ソースコードの解説
Loaderコンポーネントのソースコードを細かく分けて解説していきます。ファイルはtsxです。
use client
"use client";
Next.jsの公式に掲載されている「use client
」のドキュメントによると、use clientを宣言することによって、クライアント側でレンダーするコンポーネントを指定するとのこと。
またuse clientを宣言することは、クライアント側で利用可能なJavaScript機能を使ったインタラクティブなUIを作るときに行われるべきだと説明されています。
フルスタックなReactフレームワークであるNext.jsでは、クライアント側とサーバー側の処理を自明にしておかないといけないみたいです。
以下はクライアント側で利用可能なJavaScript機能の例です。
The
https://nextjs.org/docs/app/api-reference/directives/use-clientuse client
directive designates a component to be rendered on the client side and should be used when creating interactive user interfaces (UI) that require client-side JavaScript capabilities, such as state management, event handling, and access to browser APIs. This is a React feature.
後で解説する2つのフック(useEffect, useRef)がクライアント側で使うものなので、今回の実装ではuse client宣言をします。
フック
import { useEffect, useRef } from "react";
フックは下記の2つを使用。
それぞれのフックは今回の実装において下記の役割を果たします。
useEffectでアニメーションの発動タイミングを制御し、useRefでアニメーションさせる要素を参照します。
ライブラリ
import gsap from "gsap";
既に紹介した通り、ライブラリはGSAPを使用。
今回の簡単な実装でGSAPを入門しようと思います。
Loaderコンポーネント
export const Loader = () => {
Loadingアニメーションを実装するためのコンポーネントを作成。
以下にLoaderコンポーネントの中身を書いていきます。
useRefで要素を参照
const leftRef = useRef<HTMLDivElement>(null);
const rightRef = useRef<HTMLDivElement>(null);
「ファーストビューの視界が中央から左右に向かって広がる」というアニメーションを実装するので、必要なdiv要素を参照する「leftRef」「rightRef」という変数を定義。
もちろん変数名は任意です。
useEffectとGSAP
useEffect(() => {
gsap.to([leftRef.current, rightRef.current], {
duration: 1,
width: "0%",
ease: "power2.inOut",
delay: 0.5,
});
}, []);
アニメーションの発動タイミングを制御しながらGSAPを使いたいので、useEffectを使用します。
{
gsap.to([leftRef.current, rightRef.current], {
duration: 1,
width: "0%",
ease: "power2.inOut",
delay: 0.5,
});
}
useEffectの第一引数にGSAP記述を入れます。
[]
第二引数は空にします。そうすることで1レンダーに対して1度だけアニメーションさせます。

今回掲載しているソースコードだと、ページを移動するたびに1回ずつアニメーションされるよ。

そうだね。レンダーごとの回数については制御できているけど、別ページに移動したときの制御はできていないね。

1セッションに対して1アニメーションになるような実装については別記事で紹介します。
参照される要素を出力
return (
<div className={styles.loader}>
<div ref={leftRef} className={styles.left} />
<div ref={rightRef} className={styles.right} />
</div>
);
ref属性が「leftRef」「rightRef」になっているdiv要素2つ、これらが今回GSAPによってアニメーションされる要素です。
};
ここまでがLoaderコンポーネントの中身。
以上がindex.tsxソースコードの説明でした。
index.module.cssのソースコード
使用したcssは以下の通りです。
.loader {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
pointer-events: none;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
background-color: rgba(var(--color-primary-rgb), 0.96);
}
.right {
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 100%;
background-color: rgba(var(--color-primary-rgb), 0.96);
}
「position:fixed」でコンポーネント全体を固定化させつつ、「position:absolute」で左右の要素が柔軟に動けるようにしました。
これでReact上でのGSAP実装が完了です。
まとめ
以上がReact.jsでGSAPのアニメーションを実装したときの備忘録です。
今回掲載したソースコードのままだと、ページ遷移のたびにLoadingアニメーションが発動して鬱陶しい。なので、初回表示時に限定させる実装も行うことにしました。
その実装については別記事で紹介したいと思います。