様々なアニメーションが簡単に実装できるGSAPですが、ScrollTriggerを使ってスクロールに合わせて要素を順番に表示させようとしても最初の1回しかアニメーションさせることしかできません。

jQueryだったら簡単にできたことでもGSAPでは仕様が異なることがあるので、実践でハマってしまって無駄な時間を過ごさないように覚えておきましょうー!

サンプル

サンプルを見てみましょう。

See the Pen
GSAPでビューポートに入った順にアニメーションさせる パターン 2
by イロイロデザインラボラトリ (@iroirodesignlab)
on CodePen.

.boxというclassが付いた10個のピンクの要素があって、スクロールしてこの要素がビューポートに入ったら順番にアニメーションしていきます。

HTML

HTMLはこんな感じです。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    
    <section>
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box">5</div>
      <div class="box">6</div>
      <div class="box">7</div>
      <div class="box">8</div>
      <div class="box">9</div>
      <div class="box">10</div>
    </section>
    
    <script src="https://unpkg.com/gsap@3/dist/gsap.min.js"></script>
    <script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>
    <script src="./script.js"></script>
  </body>
</html>

GSAPを始めるにはまずライブラリを読み込む必要があります。CDNでも提供されているのでHTMLファイルに読み込みましょう。

<script src="https://unpkg.com/gsap@3/dist/gsap.min.js"></script>

また「ここまできたらアニメーションさせる」ということもしたいので、GSAP専用のライブラリのScrollTriggerも読み込んでおきます。

<script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>

このScrollTriggerがないとページが読み込まれたときに全てアニメーションしてしまうので、セットで覚えておくと良いですね。

どちらも</body>の直上に読み込んでおきましょう。

CSS

CSSはSCSSを使っています。

html,
body {
  height: 100%;
}

section {
  padding: 2rem;
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #ffeeee;
  padding: 10%;
  margin: 10%;
  font-size: 10vw;
}

ピンクのボックスを作っている以外のことは特に何もしていません。

JavaScript

GSAPを書いていきます。

まず普通にコーディングするとこんな感じですね。.setでアニメーションする前の状態、.toでアニメーションした後の状態のプロパティを書いていきます。

gsap.set(".box", {
  autoAlpha: 0,
  y: 64
});

gsap.to(".box", {
  autoAlpha: 1,
  y: 0
});

これでは1回しかアニメーションしないので、ページが読み込まれた瞬間に.boxが全て表示されてしまいます。

See the Pen
GSAPでビューポートに入った順にアニメーションさせる ダメなパターン
by イロイロデザインラボラトリ (@iroirodesignlab)
on CodePen.

ややこしいですよね。

というわけで、解決していきましょう。

パターン 1

パターン1はかなりシンプルな方法です。

gsap.utils.toArray(".box").forEach((target) => {
  gsap.from(target, {
    scrollTrigger: {
      trigger: target,
      start: "50% 100%"
    },
    delay: 0.5,
    duration: 0.5,
    autoAlpha: 0,
    y: 64
  });
});

.setに書いているような「アニメーションする前のプロパティのみ」を書きます。startの位置に入ったら元に戻るようにアニメーションするので、CSSでアニメーションした後の値を設定しておきましょう。

今回のようなフェードインアニメーションであればCSSに何も書かなくてもだいじょうぶですね。

こんな感じになります。

See the Pen
GSAPでビューポートに入った順にアニメーションさせる パターン 1
by イロイロデザインラボラトリ (@iroirodesignlab)
on CodePen.

パターン 2

パターン2は.setと.toを書くような感じです。

gsap.set(".box", {
  autoAlpha: 0,
  y: 64,
});

ScrollTrigger.batch(".box", {
  onEnter: (batch) =>
    gsap.to(batch, {
      delay: 0.5,
      duration: 0.5,
      autoAlpha: 1,
      y: 0,
    }),
  start: "50% 100%",
});

.setにはアニメーションする前の値、.batchの.toにはアニメーションした後の値を書きます。こちらも分かりやすいかなーと思うので、この方法でも良いですね。

こんな感じになります。

See the Pen
GSAPでビューポートに入った順にアニメーションさせる パターン 2
by イロイロデザインラボラトリ (@iroirodesignlab)
on CodePen.

さいごに

というわけで、スクロールに合わせて要素を順番に表示させたいけどうまくいかないときの解決方法でした。

軽量で使いやすいアニメーションライブラリのGSAPですが、単純なところでハマってしまうこともあるので、ぜひ覚えておきましょう。