GSAPのScrollTriggerを使って、複数のターゲットに同じアニメーションを設定する方法を紹介します。
例えばページ内にH2見出しが複数あり、それぞれが画面に表示されたタイミングでフェードインのような登場をさせたい!といった場合に参考になる方法です。
CSSでスタイルを設定するときは h2 { font-size: 24px } のように書けば、全てのh2要素に対して一括でスタイルの設定ができます。ところがこのイメージでGSAPのScrollTriggerを扱うとおそらく思い通りのふるまいになりません。
これは私自身がGSAPのScrollTriggerを学び始めた頃に悩んだ点で、GSAPを使う上で色々な応用が可能な方法だと思います。
お忙しい方のため、さっそく動くコードを紹介します!またページの一番下にHTML全体を載せていますのでこちらも参考になればと思います。
$(function(){
gsap.utils.toArray("h2").forEach(target => {
gsap.from(target, {
scrollTrigger: {
trigger: target,
},
opacity: 0,
yPercent: 100,
});
});
});
以下、このコードについて深掘りしています。私がつまずいたポイントや別の記述方法、実践向けのアイデアなどを紹介していますので興味のある方はぜひご一読ください♪
※本記事ですが予想以上に好評のようでしたので改めて整理しなおしました。
ScrollTriggerで複数のターゲットに同じアニメーションを設定するにはどうしたらよいか?
この記事では、ページ内にH2見出しが複数あり、各々がスクロールによって画面に表示されるタイミングで同じアニメーションを開始する。というふるまいを例に方法などを紹介します。
間違いやすいScrollTriggerの書き方
まず、ScrollTriggerを使って複数のターゲットに同じアニメーションを設定する。という目的を実現しようとするコードでありがちな間違いをご紹介します。
順にいきます。全てのH2に対して、フェードインアップアニメーションを実現するには、GSAPで以下のような書き方ができると思います。
$(function(){
gsap.from("h2", {
opacity: 0,
yPercent: 100,
});
});
これをスクロールと連動させたいので、scrollTriggerオプションの追加を行います。
すると以下のような書き方にたどり着きやすいのではないでしょうか。私も最初こう書きました…
$(function(){
gsap.from("h2", {
scrollTrigger: {
trigger: "h2",
},
opacity: 0,
yPercent: 100,
});
});
これが思い通りに動かない例です。全てのH2要素に対して設定しているようで、一見問題ないように見えます。ところがこの書き方だと、一番最初のH2が画面に入ったタイミングで、全てのH2が同時にアニメーション開始するというふるまいをします。
つまり、最初に登場するH2は想定したフェードインアニメーションが見られるのですが、以降のH2はアニメーションが見られません。すでにアニメーションが終了しているからです。
やりたいのはそういうことではなく、H2が画面に表示される度にそれぞれのH2が独立してアニメーションしてほしいです。
ScrollTriggerを複数ターゲットに設定するときの考え方
目標を実現するためには、複数のターゲットを一旦配列に格納してからforEach()でグルグルと各ターゲットに対してアニメーションの設定をするという考え方が使えます。
gsapには「gsap.utils」という便利なオブジェクトが用意されています。このユーティリティオブジェクトの中に、配列を扱う「toArray()」というメソッドがありますので、こちらを利用します。
var targets = gsap.utils.toArray("h2");
これでtargetsにターゲットとしたいH2全てが配列として取得できました。次に配列になったtargetsをforEach()を使って各H2に対して順にアニメーションの設定を行います。
これは普通のjavascriptの構文です。またGSAPの公式ページなどでよく見かけるサンプルコードを見ると、アロー関数を使う傾向があるみたいです。
targets.forEach(target => {
// ここで共通のアニメーションを設定する
});
アロー関数ではなく従来のfunction()を使って次のような書き方もできます。
targets.forEach(function(target) {
// ここで共通のアニメーションを設定する
});
また、手順を紹介するために一旦targetsという配列に格納する書き方をしましたが、これは以下のように「.」で繋いでひとつづきに書くこともできます。
gsap.utils.toArray("h2").forEach(target => {
// ここで共通のアニメーションを設定する
});
慣れてきたり、forEachを使う前に特別に配列をさわる必要がなければ、1行で済むので最もスッキリとした書き方になるのかなと思います。
あとは、この中にgsapの設定を記述していきます。
アロー関数を使った書き方
こちらが冒頭で紹介したソースコードです。
$(function(){
gsap.utils.toArray("h2").forEach(target => {
gsap.from(target, {
scrollTrigger: {
trigger: target,
},
opacity: 0,
yPercent: 100,
});
});
});
ポイントは、アロー関数の引数として「target」を置いて、これをgsap.from()の第1引数とscrollTriggerオプションのtriggerに指定するというところ。
配列に格納した個々のターゲットが、forEachの繰り返しの処理の度に入れ替わりtargetに入ってくるので、各々のターゲットに対して次々と同じアニメーションを設定できるということです。
※先の上手く動かない例で、直接”h2″を指定していた部分をtargetにするということです。
function()を使った書き方
アロー関数に慣れていない方は、forEach()の中を従来のfunction()を使って以下のように書くこともできます。
gsapの中身は上記と同じですが、参考までに紹介しておきます。
$(function(){
gsap.utils.toArray("h2").forEach(function(target) {
gsap.from(target, {
scrollTrigger: {
trigger: target,
},
opacity: 0,
yPercent: 100,
});
});
});
ScrollTriggerを複数ターゲットに設定するときのクラス名の提案
ここまでの例では、要素のセレクタを以下のように”h2″で指定しました。
var targets = gsap.utils.toArray("h2");
わかりやすさ重視で紹介しているので、実践で使うときはそれ用のクラスを付けてコントロールした方が便利ではないかと思います。
私がよく実践するのは、以下のようにfadeInUpというクラスでスクロール連動のアニメーションをコントロールする方法です。
<h2 class="fadeInUp">見出し2</h2>
合わせて複数ターゲットを以下のようにクラス名で取得します。
var targets = gsap.utils.toArray(".fadeInUp");
あとは同じです。
こうすることで、スクロール連動でフワッと表示させたい要素にfadeInUpというクラスをつける。という使い方ができるようになります。
サンプルのような<h2>の他色々なところで登場する<section>や<div>などでもクラスにfadeInUpを追加してあげることで、同じふるまいを効率よく設定できます。
余談:$(function(){})や変数名について
今回の例ではしれっと、$(function(){})の中に書いています。こちらはjQueryでおなじみ「HTMLを読み込んだら中の処理を実行する」というものですね。
GSAPは、あるターゲットに対してアニメーションの設定を行うので、コード実行前に必ずHTML要素が存在していなければなりません。
ソースコード全体を見渡せるようなシンプルなファイルで、確実に最後の方でスクリプトを実行できれば$(function(){})は不要ですが、書いておけばスクリプトの読み込み場所を気にしなくてよいので、個人的に好みで書いています。
また、今回任意に付けた「targets」や「target」はもちろん何でも良いです。「t」だけでも動きはしますが変数名は多少長くても分かりやすく誤解されにくいものがよいかと思います。
まとめ
GSAPのScrollTriggerを使って、複数のターゲットに同じアニメーションを設定する方法を紹介しました。
この技を使えばアニメーションの使い回しもできるのではないかと思います。また同じアニメーションとして1箇所で設定できるのでメンテナンス的にも効率良いコードが期待できます。
最後にHTML全体を載せておきます。コピペして使っていただいても構いませんが、あくまでもシンプル重視で余分を削っていますので、動作の参考程度にしていただけたらと思います。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>SAMPLE</title>
<style>
section { height: 100vh; padding: 20px; text-align: center; }
section:nth-child(2n){ background-color: lightgray; }
</style>
</head>
<body>
<section>
<h1>PAGE TITLE (H1)</h1>
</section>
<section>
<h2>SECTION1 (H2)</h2>
</section>
<section>
<h2>SECTION2 (H2)</h2>
</section>
<section>
<h2>SECTION3 (H2)</h2>
</section>
<script src="//code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/ScrollTrigger.min.js"></script>
<script>
$(function(){
gsap.utils.toArray("h2").forEach(target => {
gsap.from(target, {
scrollTrigger: {
trigger: target,
},
opacity: 0,
yPercent: 100,
});
});
});
</script>
</body>
</html>
ぜひ素敵なホームページを作成してください♪