PORTFOLIO & WEB DESIGN MEMORANDOM BLOG   
PORTFOLIO & WEB DESIGN MEMORANDOM BLOG   

GSAPで複数のボックスに同じスクロールアニメーションを付ける

タグ :

「画像・見出し・リスト・文章」が入ったボックスが複数あるとき、ボックスごとにJavaScriptを書く必要はありません。

ボックスをすべて集めて、1つずつ同じアニメーションを設定します。

サンプルコード

HTML

1<div class="box-wrapper">
2
3  <article class="box">
4    <div class="top">
5      <div class="thumb">
6        <img src="./images/thumb01.jpg" alt="サービスのイメージ">
7      </div>
8
9      <div class="text">
10        <p class="en">FEATURE 01</p>
11        <h3>コストと手間を減らせます</h3>
12
13        <ul>
14          <li>現地に行かずに再現できる</li>
15          <li>天候に左右されない</li>
16          <li>スタッフの手配が少なくて済む</li>
17        </ul>
18      </div>
19    </div>
20
21    <div class="bottom">
22      <p class="sentence">
23        商品やサービスの魅力を、わかりやすく伝えます。
24      </p>
25    </div>
26  </article>
27
28  <article class="box">
29    <!-- 1つ目と同じ構造のボックスを追加 -->
30  </article>
31
32</div>

大切なのは、すべてのボックスが同じ構造になっていることです。

1.box
2├─ .top
3│  ├─ .thumb     … 画像
4│  └─ .text
5│     ├─ .en     … 英語の小見出し
6│     ├─ h3      … 見出し
7│     └─ ul > li … リスト
8└─ .bottom
9   └─ .sentence  … 説明文

JavaScript

ScrollTrigger を使うため、最初に登録します。

1gsap.registerPlugin(ScrollTrigger);
2
3const featureBoxes = gsap.utils.toArray(".box");
4
5featureBoxes.forEach((target) => {
6  // 今処理している box の「中だけ」から部品を探す
7  const thumb = target.querySelector(".thumb");
8  const headings = target.querySelectorAll(".en, h3");
9  const listItems = target.querySelectorAll("li");
10  const sentence = target.querySelector(".sentence");
11
12  // この box 専用のアニメーション予定表を作る
13  const timeline = gsap.timeline({
14    defaults: {
15      opacity: 0,
16      y: 30,
17      duration: 0.6,
18    },
19    scrollTrigger: {
20      trigger: target,
21      start: "top 75%",
22    },
23  });
24
25  // 表示する順番を予定表に追加する
26  timeline
27    .from(thumb)
28    .from(headings)
29    .from(listItems, { stagger: 0.15 })
30    .from(sentence);
31});

コードの仕組み

1. .box を全部集める

1const featureBoxes = gsap.utils.toArray(".box");

これはページ内の .box を全部集める処理です。

1featureBoxes = [1つ目のbox, 2つ目のbox, 3つ目のbox]

ボックスをHTMLに追加しても、JavaScriptは書き足さなくて大丈夫です。

2. ボックスを1つずつ処理する

1featureBoxes.forEach((target) => {

forEach は「集めたボックスを、1つずつ順番に処理する」という意味です。
1回目は1つ目のボックス、2回目は2つ目のボックスが target になります。

3. いまのボックスの中だけを探す

1const thumb = target.querySelector(".thumb");

target.querySelector() は、「いま処理中の .box の中から .thumb を探す」という意味です。
つまり、1つ目のボックスを動かすときに、2つ目のボックスの画像を間違えて選ぶことがありません。

4. 見えたらアニメーションを始める

1scrollTrigger: {
2  trigger: target,
3  start: "top 75%",
4},

target の上端が画面の下寄り(75%の位置)まで来たら、そのボックスのアニメーションが始まります。

5. timeline に表示する順番を書く

1timeline
2  .from(thumb)
3  .from(headings)
4  .from(listItems, { stagger: 0.15 })
5  .from(sentence);

.from() は「見えない状態から、元の見た目へ表示する」という命令です。

1画像
23小見出し・見出し
45リスト(1行ずつ)
67説明文

stagger: 0.15 を付けたリストは、各 li が0.15秒ずつずれて、順番に表示されます。

まとめ

この書き方は、次の3段階でできています。

11. .box を全部集める
22. 1つずつ中の部品を探す
33. その box 専用のアニメーションを作る

「同じ形のコンテンツが繰り返されるページ」で、とても使いやすい設計です。

MILMONA   MILMONA   MILMONA   MILMONA   MILMONA   
MILMONA   MILMONA   MILMONA   MILMONA   MILMONA