数行で実装!ScrollTriggerの toggleClass で作るスクロール連動アニメーション

Webサイトのスクロール連動アニメーション、皆さんは普段どうやって実装していますか?

以前の記事では、素のJavaScript(Intersection Observer)を使って、ブラウザに負担をかけずに軽量でクラスを付与する方法をご紹介しました。

パフォーマンスを最優先するなら以前の方法がベストですが、後から「もっと複雑なパララックス(視差効果)を入れたい」「スクロールに合わせて複数の要素を連続で動かしたい」といった追加の要望が出ることがよくあります。

そんな、将来的なアニメーションの拡張を見据えた時に強力な武器になるのが、世界中で大人気のアニメーションライブラリ「GSAP(GreenSock Animation Platform)」です!

GSAPを使うメリット
ライブラリを読み込む分、素のJavaScriptよりファイルサイズは大きくなりますが、その代わりに「コードの記述量が圧倒的に少なくなる」・「後から複雑なアニメーションへ簡単に変更できる」というメリットがあります。

今回はGSAPの拡張プラグインである ScrollTriggertoggleClass という機能を使い、驚くほど短いコードでサクッとクラス付与を実装する方法をご紹介します!

実際のデモ動作

See the Pen Untitled by yoshi (@mikanbako) on CodePen.

全画面でのデモ動作は以下のリンクからご確認下さい!(別タブで開かれます)

実装コードの紹介

それでは、実装コードを見ていきましょう。 今回は「クラスを付け外しする仕組み」自体をGSAPに任せるため、HTMLとCSSは以前の記事と全く同じものを使用します。

【HTML】

<div class="p-spacer">下にスクロールしてみてね ↓</div>
<div class="p-box js-scroll-target">フワッ!</div>
<div class="p-spacer">もっとスクロール ↓</div>
<div class="p-box js-scroll-target">フワフワッ!</div>
<div class="p-spacer">ここまで見てくれてありがとう!</div>

【CSS】

.js-scroll-target {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}

.js-scroll-target.is-active {
  opacity: 1;
  transform: translateY(0);
}

【JavaScript】

大きく変わるのはJavaScriptです。GSAPの ScrollTrigger を使うと、コードはこれだけ短くなります!

gsap.utils.toArray('.js-scroll-target').forEach(target => {
  ScrollTrigger.create({
    trigger: target,          // 監視する要素
    start: "top 60%",         // 発火する位置
    toggleClass: "is-active", // 付与するクラス
    once: true                // 1回だけアニメーションさせる
  });
});

以前の記事での Intersection Observer で書いていた「交差判定の if 文」や「クラスを add する処理」、さらには「監視の解除処理」まで、すべてオプション設定ひとつで完結してしまいました!

コードの解説・こだわったポイント

GSAPを使う最大のメリットは、この「直感的なコードの短さ」と「圧倒的な拡張性」にあります。
今回の実装におけるこだわりポイントを解説します!

toggleClass でサクッと実装

スクロール連動で一番面倒なのは「画面に入ったらクラスを付ける」「外れたら外す」という条件分岐の記述です。 ScrollTrigger に用意されている toggleClass: "is-active" というオプションを使えば、そのような複雑な分岐を書くことなく、一行でクラスの制御をGSAPに丸投げできます。

start プロパティで直感的な位置調整

以前の Intersection Observer では rootMargin: "0px 0px -40% 0px" のように少し頭を使う計算が必要でしたが、GSAPなら非常に直感的に書けます。

start オプションついて
start: "top 60%" という指定は、「対象要素の top (一番上)が、画面の 60% の位置(上から60%)に来た時」という意味になります。 言葉の通りに設定できるので、後からの微調整も非常にスムーズです。

once: true で無駄な監視をストップ!

今回も、一度フワッと表示されたらそれ以降はアニメーションしなくて良い要件なので、once: true を指定しています。 これにより、以前の unobserve と同じように、一度アニメーションが発火した要素の監視をストップしてくれるため、パフォーマンスへの配慮もバッチリです。

将来の拡張性を担保する

これだけシンプルな実装であれば、以前の Intersection Observer の方がファイルサイズも軽く済みます。 しかし、「後から別の要素に時間差(stagger)でアニメーションを付けたい」「スクロール量に合わせて要素をピン留め(pin)したい」といった複雑な要件が追加される可能性がある場合は、最初からGSAPを導入しておくことで、後々の改修コストを大幅に抑えることができます!

まとめ

今回は、GSAPの ScrollTrigger プラグインを使って、スクロールに合わせて要素にクラスを付与する実装方法をご紹介しました。

ここ最近の記事を通して、固定ヘッダーの被り防止(CSS)、軽量なクラス付与(Intersection Observer)、そして今回の拡張性を意識したクラス付与(GSAP)と、スクロールに関連する複数のアプローチをまとめてきました。

これらを実装・比較してみて改めて感じるのは、「常に1つの絶対的な正解があるわけではなく、プロジェクトの要件や将来的な展望に合わせて最適な技術を選択する力」の大切さです。

とにかくパフォーマンス(軽さ)を重視するのか、今後のリッチなアニメーション追加(拡張性)を見据えるのか。 その時々の状況に応じて、CSS、素のJavaScript、外部ライブラリといった手札の中から一番ベストなカードを切れるように、これからもフロントエンド技術の引き出しをどんどん増やしていきたいと思います!

最後まで読んでいただき、ありがとうございました!

Prev
Next