【ScrollTrigger】forEach文を使用した繰り返し処理とスクロール量に合わせたアニメーション

はじめに

この記事の概要

こんにちは、株式会社TOKOSエンジニアのスギタです!
今回は、GreenSock社が開発したGreenSock Animation Platform(GSAP)ScrollTriggerを使いスクロールアニメーションを行ってみようと思います。
またGSAPでの繰り返し処理とスクロール量に合わせたアニメーションも合わせて行っていきたいと思います。
また基本的なGSAPの使いかたやScrollTriggerの使い方がわからないかたは下記の記事を参考にしてください!!!

【初学者向け】GSAPでテキストアニメーションをやってみた!! 【ScrollTrigger】スクロールするとふわっと浮き出るスクロールアニメーション

対象読者

  • web制作でアニメーションの実装をしたい方

今回の完成予定

今回はテキストに対して、以前やったスクロールするとふわっと浮き出るアニメーションに加え画像にはスクロール量に対して画像の位置が変わるアニメーションを行っていきます。

GSAPとScrollTriggerの導入

GSAPを利用するには、オフィシャルサイトからダウンロードするか、CDNでも提供されているので公式HPを参照してください。
今回はCDNを利用していきたいと思います。

注意

ScrollTriggerを使用する際、GSAPに依存しているため、GSAPとScrollTrigger両方読み込まないといけません。

コードの紹介

では一つずつ分解して紹介していきます。

レイアウトを整える

HTML

<body>
  <div class="fv">
  </div>
  <div class="layout">
    <div class="content">
      <div class="wrapper js-scroll">
        <img src="./img/image1.jpg" alt="山" class="image ">
      </div>
      <p class="text js-scroll-text">私も生涯人知れずその観察者というのの時を入ったん。現に当時に講演学はつるつるこうした附随なけれありでもをしてくれなかっをは注意したたて、そうとはついたないなです。徳義にぶらです方はまあ前にけっしてあるたです。おもに岡田さんで相当主義そう話が借りた亡骸この壇これか随行がというご話たたましだろから、同じ昔は私か珍個性をあるて、嘉納さんののを取消の私を単にお注意とならてそこ空腹にご観念をあるように同時におお話をするありたので、ただいまはたして記憶が当てべきでいですのに上げだっん。またするとお教授でもっのはそれだけ危険と云うないが、この徳義心へもなりだがという中腰をさておりまします。</p>
    </div>
    <div class="content">
      <p class="text js-scroll-text">私も生涯人知れずその観察者というのの時を入ったん。現に当時に講演学はつるつるこうした附随なけれありでもをしてくれなかっをは注意したたて、そうとはついたないなです。徳義にぶらです方はまあ前にけっしてあるたです。おもに岡田さんで相当主義そう話が借りた亡骸この壇これか随行がというご話たたましだろから、同じ昔は私か珍個性をあるて、嘉納さんののを取消の私を単にお注意とならてそこ空腹にご観念をあるように同時におお話をするありたので、ただいまはたして記憶が当てべきでいですのに上げだっん。またするとお教授でもっのはそれだけ危険と云うないが、この徳義心へもなりだがという中腰をさておりまします。</p>
      <div class="wrapper js-scroll">
        <img src="./img/image2.jpg" alt="山" class="image">
      </div>
    </div>
    <div class="content">
      <div class="wrapper js-scroll">
        <img src="./img/image3.jpg" alt="山" class="image">
      </div>
      <p class="text js-scroll-text">私も生涯人知れずその観察者というのの時を入ったん。現に当時に講演学はつるつるこうした附随なけれありでもをしてくれなかっをは注意したたて、そうとはついたないなです。徳義にぶらです方はまあ前にけっしてあるたです。おもに岡田さんで相当主義そう話が借りた亡骸この壇これか随行がというご話たたましだろから、同じ昔は私か珍個性をあるて、嘉納さんののを取消の私を単にお注意とならてそこ空腹にご観念をあるように同時におお話をするありたので、ただいまはたして記憶が当てべきでいですのに上げだっん。またするとお教授でもっのはそれだけ危険と云うないが、この徳義心へもなりだがという中腰をさておりまします。</p>
    </div>
  </div>
</body>

CSS

/* resetcssは省略 */
body {
  background-color: black;
}

.fv {
  width: 100vw;
  height: 100vh;
}

.layout {
  width: fit-content;
  margin: auto;
  padding: 200px 16px;
}

.content {
  display: flex;
  align-items: center;
  gap: 0px 40px;
  margin-top: 120px;
}

.wrapper {
  max-width: 600px;
}

.image {
  width: 100%;
  height: auto;
}

.text {
  max-width: 600px;
  color: #fff;
}

あまり説明することはありません。お好きなフォントとレイアウトにしちゃってください!

前回の確認

ではまず以前紹介したような、スクロールの位置に対して、フワッて浮き出てくるアニメーションをテキストに実装していきたいと思います。
まずは前回のコード確認をします。

gsap.fromTo(
  ".hoge1",
  { y: 20, autoAlpha: 0 },
  {
    y: 0,
    autoAlpha: 1,
    scrollTrigger: {
      trigger: ".hoge",//triggerさせる要素をアニメーションが始まる直前の要素を指定していた
      start: "bottom top"
    },
  }
);
gsap.fromTo(
  ".hoge2",
  { y: 20, autoAlpha: 0 },
  {
    y: 0,
    autoAlpha: 1,
    scrollTrigger: {
      trigger: ".hoge1",//triggerさせる要素をアニメーションが始まる直前の要素を指定していた
      start: "bottom top"
    },
  }
);

前回はScrollTrigger内の記述でtrigger:直前の要素,にしていたと思います。
それでは、アニメーションをかけたい要素の数分の記述が必要になってしまいます。細かく一つずつ指定できるのは良いかもしれませんがやはり記述量が多くなってしまします。
やはり同じアニメーションであれば、繰り返し処理などを使って処理するべきです。

Utility Methodsの使用

では繰り返し処理をしようとした場合は要素を配列に格納する必要があります。
そのためにGSAPではいろいろなことができるUtility Methodsという様々な便利なメソッドを用意してくれています。
興味のある方は下記を参照してみてください。

今回Utility Methodsの中のtoArray()メソッドを使用していきます。
このメソッドはセレクター用いて要素を取得し、配列に格納してくれます。
例)toArray(.class) ==> [element,element2]このように要素を指定し配列に格納していってくれます。
ではこのことを踏まえクラス名.js-scroll-textを配列に入れていきたいと思います。
gsap.utils.toArray(.hoge);で配列の生成できます。

const texts = gsap.utils.toArray(".js-scroll-text");

これでtextsという配列を生成することができました。
ではこれに対してforEach文で繰り返し処理を行っていきたいと思います。

const texts = gsap.utils.toArray(".js-scroll-text");
texts.forEach((text) => {
  gsap.fromTo(
    text,
    {
      y: 40,
      autoAlpha: 0,
    },
    {
      y: 0,
      autoAlpha: 1,
      scrollTrigger: {
        trigger: text, //アニメーションが始まるトリガーとなる要素
        start: "top-=100px center", //アニメーションが始まる位置
      },
    }
  );
});

これでテキストに対しアニメーションの実装の完了です。
ScrollTrigger内の記述でトリガーとなる要素は、前回はアニメーションが始まる直前の要素にしていましが、今回はアニメーションの対象の要素にしています。
そのほうが直前の要素名に依存せず、使いまわしがより柔軟にできると思います。
これでテキストに対するアニメーションは完了です。

スクロール量に合わせたアニメーションの実装

それでは次にスクロール量に合わせた、アニメーションの実装です。
では早速紹介していきます。

const images = gsap.utils.toArray(".js-scroll");
images.forEach((image) => {
  gsap.to(image, {
    y: -100,
    scrollTrigger: {
      trigger: image,
      start: "top center",
      end: "bottom center",
      scrub: 1,
    },
  });
});

今回も先程紹介した、繰り返し処理をもとに実装していきます。
今回はto()メソッドで指定しています。
ScrollTrigger内の記述でいつもと違う箇所があります。
end: “bottom center”,scrub:1,です。これが、スクロール量に対しての記述になります。 
分かりづらいと思いますのでmakers:true,にして確認していきます。

const images = gsap.utils.toArray(".js-scroll");
images.forEach((image) => {
  gsap.to(image, {
    y: -100,
    scrollTrigger: {
      trigger: image,
      start: "top center",
      end: "bottom center",
      scrub: 1,
      markers: true,
    },
  });
});


startendでアニメーションの開始地点と終了地点を指定し,それに対しscrubでスクロール量に対してアニメーションしてねという感じです。
scrub:スクロールに対しての遅延する秒数,という指定方法になります。
これでスクロールごとに1秒間アニメーションを実行させることができるようになります。

さいごに

今回はスクロールアニメーションの繰り返し処理とスクロール量に対してのアニメーションの実装を行いました。
今回紹介したUtility MethodstoArray()メソッド以外にも使えそうなメソッドがありましたので、また別の機会に使用してみようと思います。
またスクロール量に対してのアニメーションも最近のモダンなHP等ではよく見かけるので、使用できるようになると表現の幅も広がるなと感じました。