• Skip to primary navigation
  • Skip to main content

Nagashima Laboratory

  • Home
  • Lecture
  • Note
  • Index
  • About

スクロールアニメーション(JavaScript)

JavaScriptのIntersection Observer APIと、Web Animations APIを組み合わせて、スクロールによって反応するアニメーション効果を加えます。

キーワード:Intersection Observer API、Web Animations API、配列、繰り返し(forEach)

作成例(完成イメージ)

  • 作成例:https://ngsm-syr.github.io/javascript_scroll/
  • コード:https://github.com/ngsm-syr/javascript_scroll/

【準備】フォルダ:javascript_scroll

①JavaScriptを書くための準備で作成したフォルダ(空のHTML、CSS、JavaScriptが入っている)を準備します。GitHubからもダウンロードできます。

②フォルダの名前を「javascript_scroll」に変更します

③画像を3枚程度用意します。作例と同じ画像を使う方は、Githubからダウンロードしてください。

画像は images フォルダに入れます。

HTMLとCSSファイルの準備

まず、コンテンツ部分を用意します。

▼index.html

  <header>
    <h1>SCROLL</h1>
  </header>
  <main>
    <img src="images/img01.png" alt="img01" id="img01">
  </main>

▼style.css

body {
  text-align: center;
}

h1 {
  margin: 50vh 0;
}

img {
  max-width: 100%;
}

Intersection Observer APIとは

ターゲットとなる要素が、指定領域(ビューポート)に入ったかどうかを検知する方法です。これによって、スクロールして、ターゲット要素が範囲に入ったときに、動作を呼び出すことができます。要素が範囲に入ることを「交差」と表現します。

Intersection→交差
Observer→監視者

【補足】従来、スクロールによって反応する仕組みをつくるには、scrollイベントを使う必要がありました。イベントが起こるタイミングを割り出すのに、画面サイズが変わるたびに再計算が必要なため、負荷のかかる方法でした。

Intersection Observer API の使い方

①監視対象が現れたときに実行したい内容を定義する

▼script.js

//実行する機能
const show = () => {
  console.log('ログを表示');
}

【補足】アロー関数

上記のような関数の定義方法をアロー関数といいます。=>の部分が矢(arrow)のように見えることが名前の由来です。

const 関数名 = () => {
  //実行内容
}

functionを使った書き方をすると以下のようになります。

function show() {
  console.log('表示します');
}

functionを使った書き方の方が歴史が古く、アロー関数の方が新しい書き方になります。解説書等では両方見かけることがありますので、どちらの形式も確認しておいてください。

②監視機能の設定

▼script.js

//実行する機能
const show = () => {
  console.log('ログを表示');
}

//監視機能の設置
const observer = new IntersectionObserver();

③動作内容を指示

▼script.js

//実行する機能
const show = () => {
  console.log('ログを表示');
}

//監視機能の設置
const observer = new IntersectionObserver(show);

④監視対象を指示

▼script.js

const show = () => {
  console.log('ログを表示');
}

//監視機能の設置
const observer = new IntersectionObserver(show);

//監視対象の指示
observer.observe();

⑤何を監視するのかを指定

▼script.js

const show = () => {
  console.log('ログを表示');
}

//監視機能の設置
const observer = new IntersectionObserver(show);

//監視対象の指示
observer.observe(document.querySelector('#img01'));

ログが表示されるタイミングから、Intersection Observerの機能は、ページが読まれた瞬間、要素が範囲に入った瞬間、範囲から外れた瞬間に呼び出されることがわかります。

  • 途中経過:https://ngsm-syr.github.io/javascript_scroll_a/
  • コード:https://github.com/ngsm-syr/javascript_scroll_a/

⑥監視対象の情報取得

Intersection Observer APIでは、対象要素のサイズ、名前などの情報が「配列」で渡されます。次のように書くと、配列に渡される情報が確認できます。

▼script.js

const show = (entries) => {
  console.log(entries);
}

0番目の配列のみ取得
(画像が1つのため、先頭の配列のみを取得)

▼script.js

const show = (entries) => {
  console.log(entries[0]);
}

要素を取得

▼script.js

const show = (entries) => {
  console.log(entries[0].target);
}

⑦アニメーションを加える

▼script.js

const show = (entries) => {
  const keyframes = {
    opacity: [0, 1],
    translate: ['200px 0',0]
  }
  entries[0].target.animate(keyframes,600);
}
  • 作成例:https://ngsm-syr.github.io/javascript_scroll/
  • コード:https://github.com/ngsm-syr/javascript_scroll

【応用】複数の要素に別々の動きを設定する

3枚の画像に、それぞれ別の動きを設定した例です。

  • 途中経過:https://ngsm-syr.github.io/javascript_scroll_b/
  • コード:https://github.com/ngsm-syr/javascript_scroll_b/

【応用】複数の要素に同じ動きを設定する

同じクラス名をつけた要素に、同じ動きができるように、繰り返し処理を使って設定します。

▼index.html

    <img src="images/img01.png" alt="img01" class="img">
    <img src="images/img02.png" alt="img02" class="img">
    <img src="images/img03.png" alt="img03" class="img">

すべての画像に同じクラス名を追加します。

▼style.css

img {
  max-width: 100%;
  margin: 20vh 0;
}

画像同士がくっつかないように上下にマージンを設定します。

▼script.js

const show = (entries) => {
  entries.forEach((entry) => {
      const keyframes = {
        opacity: [0, 1],
        translate: ['200px 0',0]
      }
      entry.target.animate(keyframes,600);
  });
}

const observer = new IntersectionObserver(show);

//監視対象
const images = document.querySelectorAll('.img');
images.forEach(img =>{
  observer.observe(img);
});

複数の要素に同じ動作をさせるため、forEachを使って、繰り返しの処理をします。

交差しているときだけ動作するようにします。

▼script.js

//交差しているときだけ
const show = (entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting){
      const keyframes = {
        opacity: [0, 1],
        translate: ['200px 0',0]
      }
      entry.target.animate(keyframes,600);
    }
  });
}

スクロールのたびに動作すると、煩わしいときもありますので、一度表示したあとは、動作しないようにします。監視対象から外すことで実現します。

▼script.js

//一度表示したら動作を止める
const show = (entries, obs) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting){
      const keyframes = {
        opacity: [0, 1],
        translate: ['200px 0',0]
      }
      entry.target.animate(keyframes,600);

      //一度表示されたら止める
      obs.unobserve(entry.target);
    }
  });
}
  • 途中経過:https://ngsm-syr.github.io/javascript_scroll_c/
  • コード:https://github.com/ngsm-syr/javascript_scroll_c/

参考書籍・リンク

  • 「すらすらわかるJavaScript 新版」桜庭洋之,望月幸太郎, 翔泳社,2022
  • 「1冊ですべて身につくJavaScript入門講座」Mana, SBクリエイティブ, 2023
  • 「独習JavaScript」CodeMafia 外村将大, 翔泳社, 2021
  • https://developer.mozilla.org/ja/docs/Web/API/IntersectionObserver
  • https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API

2023-10-27 (Last Modified: 2024-10-31) Category: 資料 Tags:javascript

Copyright © 2023–2025 · Nagashima Sayuri Laboratory