サイト制作をしていると、こんな要望が出てくることがあります。

画面をスクロールしたら、数字がゼロから特定の値まで増えていくアニメーションを付けたいんだけど。
どういうことか言うと、採用サイトやコーポレートサイトなどで、何らかの数値を見せることがありますよね。
採用サイトだったら男女比の数値とか、コーポレートサイトだったらこれまでの実績数値など。
そういった数値にアニメーションを付けてカッコよく協調するときに使用されるのが、数字は最初ゼロなんだけど、スクロールして画面内にその要素が入ったら、ゼロから任意の数値まで増えていく「カウントアップ」という手法です。
実装頻度はそこまで多くありませんが、多くないからこそ、実装方法を知らないまま過ごしてしまいがちです。
「jquery-numerator.js」というjQueryライブラリで実装できて簡単なので、方法をご紹介します。
jquery-numerator.jsは現在も利用できますが、GitHubリポジトリは長期間大きな更新がありません。既存サイトの保守や同ライブラリを指定された案件向けに元の実装方法を残し、記事後半ではjQueryに依存しない標準JavaScript版も紹介します。
jQueryライブラリを利用して簡単に実装できるアニメーションを他にもご紹介しているので、よろしければご覧ください。


本記事の執筆者:マサトラ
フリーランス歴4年のWebエンジニア。現在は20社以上のWeb制作会社社様と提携し、WordPress構築やLP制作を中心に月3~5件のペースでサイト制作を手がけています。
このブログでは、実務で得た知識やノウハウ、制作現場での気づきを、フリーランスとして活動中の方はもちろん、これからWeb制作を仕事にしたいと考えている方にも役立つよう発信しています。
まずは、jquery-numerator.jsを使用して、スクロールした時のカウントアップの動きを見てみましょう。
以下のCODE PENのResult画面でスクロールしてアニメーションの動きを確かめてみてください。
See the Pen 数字のカウントアップアニメーション by Sugar (@ms_da_13) on CodePen.
今回、こういったアニメーションを実装する方法を解説していきます。
jquery-numerator.jsの導入方法
では、jquery-numerator.jsの導入方法を順番に説明していきます。
ファイルのダウンロード
まず、JSファイルをダウンロードします。
jquery-numerator.jsのGitHubから必要なファイルをダウンロードしましょう。

上の画像のとおり、まず緑色の「Code」ボタンをクリックし、展開されたエリアの中に「Download ZIP」というリンクがあるので、そちらをクリックしてください。
「jquery-numerator-master.zip」というファイルがダウンロードされるかと思います。

ダウンロードした「jquery-numerator-master.zip」を解凍したら、フォルダ内に↑の画像赤枠のように「jquery-numerator.js」があります。
使用するのはこのJSファイルのみとなります。
ダウンロードしたファイルを読み込む
次に、ダウンロードしたファイルを読み込みましょう。
jquery-numerator.jsはjQueryのライブラリなので、使用するにはjQuery本体を先に読み込む必要があります。
~~~省略~~~
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
<script src="js/jquery-numerator.js"></script>
</body>
</html>上記のように、
- bodyタグの終了直前に
- jQueryの本体(今回はCDNで読み込み)を先に
- jQuery本体の後にjquery-numerator.jsを格納したパス(今回はjsフォルダ内に格納)
の順番で読み込みましょう。
コードの説明
ファイルの読み込み準備が完了したら、jquery-numerator.jsを動かすためのコード記述に移ります。
HTML
HTMLは以下のとおりです。
<div class="box">
<div class="box-item js-countUp">
<span>社員数</span>
<span class="number" data-num="150">0</span>
<span>人</span>
</div>
</div>ポイントは、
- スクロールしたらカウントアップを発火させるために、
.js-countUpというクラス名(任意の名前でOK)を付ける - カントアップさせる数字に
.numberというクラス名(任意の名前でOK)を付け、数字はゼロに(ゼロからカウントアップ開始) - カウントアップさせる数字にdata-num属性を付け、カウントアップの最大数値を入力
という点です。
jquery-numerator.jsを動かすうえでCSSは特に必要が無いので、サイトデザインに合わせて適宜CSSを当ててください。
では、jQueryに移ります。
jQuery
jQueryは以下のとおりとなります。
$(function () {
$(window).on("load scroll", function () {
$(".js-countUp").each(function () {
var txtPos = $(this).offset().top;
var scroll = $(window).scrollTop();
var windowHeight = $(window).height();
if (scroll > txtPos - windowHeight + windowHeight / 5) { // 画面サイズの下から1/5までスクロールしたらカウントアップを開始
if ($(".number", this).attr("data-num").indexOf(".") > -1) {
var rounding = 1;
} else {
var rounding = 0;
}
$(".number", this).numerator({ //以下はオプション
easing: "linear", // カウントアップの動き方
duration: 1000, // カウントアップにかかる時間
toValue: $(".number", this).attr("data-num"), // カウントアップする数値
rounding: rounding, // 小数点以下の桁数(初期値:0)
});
}
});
});
});何のことやら…とならないよう、部分ごとに解説していきますね。
if (scroll > txtPos - windowHeight + windowHeight / 5) { // 画面サイズの下から1/5までスクロールしたらカウントアップを開始こちらは、カウントアップさせたい要素(今回でいうと、.js-countUpというクラス名を付けた.box-item)が、画面サイズの下から1/5までスクロールされると、jquery-numerator.jsが発火するようにしています。
if ($(".number", this).attr("data-num").indexOf(".") > -1) {
var rounding = 1;
} else {
var rounding = 0;
}こちらは、カウントアップさせる数字(.number)に小数点以下が含まれている場合と、そうでない場合での表示の仕方を定義しています。
roundingの初期値は0ですが、この状態だと小数点以下は表示されず、例えば120.5という数字を入力しても120としか表示されません。
roundingの値を1にすると、小数点以下が表示されますが、小数点以下が存在しない数値(例えば120)でも、120.0というようになってしまいます。
この両方の不便さを解消するために、
入力されている数値に小数点以下がある場合のroundingは1=小数点以下も表示
そうでない数値の場合、roundingは0=小数点以下を省略
というように条件分岐しています。
$(".number", this).numerator({ //以下はオプション
easing: "linear", // カウントアップの動き方
duration: 1000, // カウントアップにかかる時間
toValue: $(".number", this).attr("data-num"), // カウントアップする数値
rounding: rounding, // 小数点以下の桁数(初期値:0)
});こちらの箇所はオプション設定です。
easing
カウントアップの動き方です。linearで、一定に数値がカウントアップするようにしています。
初期値はswingです。(アニメーションの最初と最後はゆっくり、それ以外は速く動く)
duration
カウントアップにかかる時間です。単位はミリ秒なので、1000ms=1秒となります。
カウントアップさせる要素が複数あり、それぞれの数値が異なるとしても、アニメーションにかかる時間は全て同じになります。
例えば、最大値が100と100000という2つの要素があったとして、かかるアニメーション時間は同じなので、視覚的には100はゆっくり、100,000は速くカウントアップしているように見えるので注意です。
toValue
カウントアップする数値を定義しています。.number要素のdata-numに記述した数値がカウントアップします。
rounding
小数点以下のオプションです。
オプション一覧
jquery-numerator.jsには、いくつかオプションが用意されています。
前述のオプション項目だけで十分かと思いますが、参考までに掲載しておきます。
以下の表は、GitHubに掲載されていた英文を簡単に日本語翻訳したものですので、オリジナルの英文で確認したい方はjquery-numeratorのGitHubをご確認ください。
| オプション名 | オプション説明 |
|---|---|
| easing | アニメーションのイージングを指定するオプションのパラメータ。デフォルトはswingです。 |
| duration | アニメーションの長さをミリ秒 (ms) 単位で指定するオプションのパラメーター。デフォルトは 500 (1/2 秒) です。 |
| delimiter | 1,000のように、3桁ごとに区切るために使用される文字を指定するオプションのパラメータ。 |
| rounding | このパラメータは、表示する小数点以下の桁数を指定します。デフォルトは 0 です。 |
| toValue | 数値をアニメーション化する最終的な値。 |
| onStart | アニメーションの開始時に呼び出される関数。 |
| onStep | アニメーションの各ステップで呼び出される関数。now と fx の 2 つの引数を受け入れます。 |
| onComplete | アニメーションが完了したときに呼び出される関数。 |
ライブラリを使わない標準JavaScript版
新規実装でjQueryを必要としない場合は、ブラウザー標準のIntersectionObserverとrequestAnimationFrameでも同じ動きを実装できます。外部ライブラリの更新状況に左右されにくいのがメリットです。
HTML
data-countに最終値を指定します。JavaScriptが無効でも内容が伝わるよう、要素内にも最終値を書いておきます。
<p class="count-up" data-count="1200">1,200</p>
<p class="count-up" data-count="98">98</p>
<p class="count-up" data-count="35000">35,000</p>JavaScript
const counters = document.querySelectorAll('.count-up');
const formatter = new Intl.NumberFormat('ja-JP');
const reduceMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
function animateCount(element) {
const target = Number(element.dataset.count);
if (!Number.isFinite(target)) return;
if (reduceMotion) {
element.textContent = formatter.format(target);
return;
}
const duration = 1500;
const startTime = performance.now();
function update(currentTime) {
const progress = Math.min((currentTime - startTime) / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3);
const value = Math.round(target * eased);
element.textContent = formatter.format(value);
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
animateCount(entry.target);
observer.unobserve(entry.target);
});
}, {
threshold: 0.3
});
counters.forEach((counter) => observer.observe(counter));対象が画面内へ入ると一度だけカウントアップします。unobserve()しているため、上下にスクロールしても繰り返し発火しません。また、OSで「視差効果を減らす」が設定されている場合はアニメーションを省略します。
CSSの例
.count-up {
font-size: clamp(2rem, 8vw, 5rem);
font-variant-numeric: tabular-nums;
font-weight: 700;
text-align: center;
}font-variant-numeric: tabular-numsを指定すると数字の幅が揃い、カウント中の横揺れを抑えやすくなります。アニメーション時間はJavaScript内のdurationで調整できます。
どちらを選ぶか
- 既存サイトですでにjQueryとjquery-numerator.jsを利用している:元記事の方法で保守する
- 仕様でjquery-numerator.jsが指定されている:バージョンを固定し、実機テストして使用する
- 新規サイトでjQueryが不要:標準JavaScript版を検討する
まとめ:jquery-numerator.jsで、スクロールすると数字が増えるアニメーションをカッコよく実装しよう
スクロールすると数字が増えるカウントアップアニメーションは、そこまで実装頻度は多くありません。
ただ、採用サイトで社内の数字を目立たせたり、コーポレートサイトで実績を強調したい時に、カッコよく見せることができます。
いざ、そういった状況に直面したときに、「どうやって実装するんだろう…」と悩んでしまうかもしれませんが、実は難しくないので、本記事を参考に実装してもらえたらと思います。

