本文へスキップ
HELLO!
HIGASHIYUKI®.COM
0   /   100

ローディング

ローディング中に 3 つの点が順に跳ねる

デモ

仕様

動作
DOM
種類
レシピ
動作確認
three 0.186.0・gsap 3.15.0
公開日

しくみと調整

3つのドットが左から順に跳ね、跳ねているあいだだけ色が変わります。小さなドットでも、いまどれが動いているかを目で追えるように、色の変化を足しました。右端が下りきると少し間を置いて、また左から始まります。

上がる動きは0.3秒の power2.out で、隣とは0.12秒ずつずらしています。上りを減速の曲線にしておくと、折り返した下りは加速の曲線になるので、ドットが落ちて着地したように見えます。次の周までの間は0.46秒。ここを詰めると、待っている人を急かすような速さになります。

往復の指定(yoyo と repeat)は、必ず stagger の中に書きます。外に書くと全体がひとつの動きとして往復するので、全部が順に上がりきってから、今度は逆の順に下りてきます。順番に跳ねて戻る形は、そこで崩れてしまいます。

読み込みが終わったときに止める関数も、最初から用意してあります。繰り返しを止めて要素ごと取り除くので、読み込みが済んだのにドットだけ跳ね続けることはありません。送信や一覧の読み込みのように終わりが読めない待ち時間のためのローダーで、受け取った量を数えられる処理なら、進み具合を表示するほうが待つ側は楽です。

コード

HTML
<div class="dots-loader" role="status">
  <span class="dots-loader__dot"></span>
  <span class="dots-loader__dot"></span>
  <span class="dots-loader__dot"></span>
  <span class="dots-loader__text">読み込み中</span>
</div>

CSS
.dots-loader {
  --dot: 14px;        /* 点の直径 */
  --gap: 10px;        /* 点の間 */
  --ink: #262626;     /* 静止している点の色 */
  --jump: #b27771;    /* 跳ねているあいだの点の色 */
  --ground: #f2f1ed;  /* 背景色 */
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap);
  background: var(--ground);
}

.dots-loader__dot {
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background: var(--ink);
}

/* スクリーンリーダーにだけ読まれる文言。画面には表示しない */
.dots-loader__text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

JavaScript
import { gsap } from "gsap";

const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

function createLoader(root) {
  const dots = root.querySelectorAll(".dots-loader__dot");
  // 色と大きさは CSS で決める。GSAP は var(--name) のままでは補間できないので、値を読み取って渡す
  const jump = getComputedStyle(root).getPropertyValue("--jump").trim();
  const lift = dots[0].offsetHeight * 1.3;

  // yoyo と repeat は stagger の中に書く(外に書くと、3 つがまとめて往復する)。
  // repeatDelay は、跳ね終わってから次の周が始まるまでの間
  const bounce = gsap.timeline({ repeat: -1, repeatDelay: 0.46 }).to(dots, {
    y: reduceMotion ? 0 : -lift, // 動きを減らす設定では、色の変化だけで順番を見せる
    backgroundColor: jump,
    duration: 0.3,
    ease: "power2.out",
    stagger: { each: 0.12, yoyo: true, repeat: 1 },
  });

  return {
    // 読み込みが終わったら呼ぶ。呼ぶまで跳ね続ける
    done() {
      gsap.to(root, {
        autoAlpha: 0,
        duration: reduceMotion ? 0 : 0.3,
        onComplete: () => {
          bounce.kill();
          root.remove();
        },
      });
    },
  };
}

// 例: fetch や画像の読み込みを待って loader.done()
export const loader = createLoader(document.querySelector(".dots-loader"));

インタラクションデザインについて、
お気軽にご相談ください。

ここに並べているのは、Web サイトの中で動く UI のサンプルです。新しく作るサイトに組み込むことも、いま公開中のサイトに、ボタンやヒーロー、スクロールの演出だけを足すこともできます。設計から実装までの進め方はWeb サイト制作、端末ごとの見え方や表示速度の考え方はレスポンシブウェブサイトのページにまとめています。映像として作る動きをお探しの場合はモーショングラフィックスをご覧ください。