数字カウントアップアニメーション

スクロールで表示されると、カウントアップのアニメーションが開始される数字アニメーション。
通常のHTMLに「data-countup」と「data-to」の属性を加えるだけでコピペで簡単実装。
プレーンなJSで作っているので、軽量でどんなサイトでも実装可能。
実績をPRしたいランディングページや、コーポレートサイトなどで使えるカウントアップアニメーション。

HTML

<div class="countUp">
  <dl class="countUp__item">
    <dt class="countUp__ttl">\ 2030年売上高 /</dt>
    <dd class="countUp__count">
      <span class="countUp__num" data-countup data-to="1280">0</span>
      <span class="countUp__unit">百万円</span>
    </dd>
  </dl>
  <dl class="countUp__item">
    <dt class="countUp__ttl">\ 顧客満足度 /</dt>
    <dd class="countUp__count">
      <span class="countUp__num" data-countup data-to="120">0</span>
      <span class="countUp__unit">%</span>
    </dd>
  </dl>
  <dl class="countUp__item">
    <dt class="countUp__ttl">\ 総受注件数 /</dt>
    <dd class="countUp__count">
      <span class="countUp__num" data-countup data-to="2359">0</span>
      <span class="countUp__unit">件</span>
    </dd>
  </dl>
</div>

2つの属性を加えるだけ

①数字が入っているタグに「data-countup」の属性を追加
②更に「data-to=”カウントアップ終了時の数字”」を追加

CSS

.countUp {
  display: flex;
  justify-content: center;
  gap: 30px;
  flex-wrap: wrap;
}
.countUp__item {
  text-align: center;
  font-weight: bold;
}
.countUp__ttl {
  letter-spacing: 0.1em;
}
.countUp__num {
  font-weight: bold;
  color: #FF8A16;
  font-size: 3em;
}
.countUp__unit {
  font-size: 1.5em;
}

JS

document.addEventListener("DOMContentLoaded", () => {
  const delay = 400; // ← 最初の0を見せたい時間(ms)
  const dur = 3000; // ← カウントアップにかかる時間(ms)

  const countUp = (el) => {
    const to = +el.dataset.to || 0;
    const t0 = performance.now();

    const tick = (t) => {
      const p = Math.min(1, (t - t0) / dur);
      const v = Math.floor(to * (1 - Math.pow(1 - p, 3))); // easeOut
      el.textContent = v.toLocaleString();
      if (p < 1) requestAnimationFrame(tick);
    };

    requestAnimationFrame(tick);
  };

  const els = document.querySelectorAll("[data-countup]");
  const running = new WeakMap(); // 要素ごとに「今動いてるか」管理

  const io = new IntersectionObserver((entries) => {
    entries.forEach((e) => {
      const el = e.target;

      if (e.isIntersecting) {
        if (running.get(el)) return; // 画面内で連打しない
        running.set(el, true);
        setTimeout(() => countUp(el), delay);
      } else {
        running.set(el, false);      // 画面外に出たら次回また動かす
        el.textContent = "0";        // 戻したくないなら消す
      }
    });
  }, { threshold: 0.3 });

  els.forEach(el => io.observe(el));
});

JavaScriptはコピペだけでOK!

調整するとしたら以下の秒数をお好みで。

const delay = 400; // ← 最初の0を見せたい時間(ms)
const dur = 3000; // ← カウントアップにかかる時間(ms)

実際の動き

\ 2030年売上高 /
0 百万円
\ 顧客満足度 /
0
\ 総受注件数 /
0
みんなにもシェアしてあげて!

この記事を書いた人

WEBサイトで使える“動くUI”を、コピペで実装可能にし、どこでも誰でも使えるコードに特化して発信しているフロントエンドエンジニア。
中学生で初めてコードに出会い初めてコーディングを知る。
その後、WEB制作会社のフロントエンドエンジニアとしてキャリアをスタートし、フリーランスを経て、現在はWEB制作会社の代表取締役。
コーディングによって人生を創り上げてきたからこそ、コードを通して誰かの役に立てたらという想いで、これまでの知識と経験を総動員したコードを公開中。

コメント

コメントする