Blog スタッフブログ

GSAPを使ってカウントアップアニメーションを作ろう

Category | Blog
Tag |
/ 43views

こんにちは、エンジニアの六川です。

2026年になりました。新たな年の幕開けですね!
私は寒がりなので冬があまり得意ではないのですが、今年は職場の皆さんから、誕生日プレゼントとしてマフラーをいただいたので、あたたかい冬が過ごせそうです。

さて今回は、数字をカウントアップさせるアニメーションの作り方をご紹介したいと思います。
カウントアップアニメーションを使うと、任意の値を動的に表現できるので、サイトのアクセントとしても効果的です。

参考:HANARIA(https://hanaria.jp/

本記事では、JavaScriptライブラリの一種GSAPを用いて「特定の位置に到達したら、任意の値をカウントアップさせる」という仕組みを実装していきます。
私なりに噛み砕いて解説しているので、よろしければ最後までご覧ください。

Table of contents

  1. コードの全体図
  2. コードの解説
  3. おわりに

コードの全体図

まずはコードの全体図を確認しましょう。

HTML
<section data-countup-trigger>
	<h1>Year</h1>
	<p data-countup-target data-from="0" data-to="2026">0</p>
</section>
JavaScript
const countUpTrigger = document.querySelector('[data-countup-trigger]');
const countUpTargets = document.querySelectorAll('[data-countup-target]');

countUpTargets.forEach( target =>{
	const countElement = {
		from: target.dataset.from,
		to: target.dataset.to
	}
	const numberElement = {
		count: countElement.from
	}                                  

	gsap.to(numberElement, {
		count: countElement.to,
		duration: 2,
		ease: "power4.out",
		scrollTrigger: {
			markers: true,
			trigger: countUpTrigger,
			start: 'top center',
		},

		onUpdate:()=>{
			target.textContent = Math.floor(numberElement.count) ;
		}
	})
})

コードの解説

大まかな流れは下記のとおりです。順を追って説明していきます。

  1. HTMLにdata属性で開始値、終了値を指定する
  2. data属性をJavaScriptで取得する
  3. GSAPを使って、取得した値を1つずつ繰り上げる

1.HTMLにdata属性で開始値、終了値を指定する

まずは、どの値からどの値までカウントアップさせるかをHTML側で指定します。
今回はdata属性を使って、data-toに開始値、data-fromに終了値を指定しました。data属性を使うことで、その値をJavaScriptで取得することができます。

<section data-countup-trigger>
	<h1>Year</h1>
	<p data-countup-target data-from="0" data-to="2026">0</p>
</section>

2.data属性をJavaScriptで取得する

次に、HTMLで設定したdata属性の値を取得してみましょう。data属性はdatasetプロパティを使うことで取得できます。
下記のように、属性名の data- より後の部分を使用して取得します。

const countUpTargets = document.querySelectorAll('[data-countup-target]');

console.log(countUpTargets.dataset.from); // 0
console.log(countUpTargets.dataset.to); // 2026

それぞれの値が取得できましたね。

3.GSAPを使って、取得した値を1つずつ繰り上げる

次はいよいよGSAPの出番です。
今回はスクロールをトリガーとして、可視領域に入ったらカウントアップを発動させたいと思います。
まずは、要素の数だけアニメーションを動作させたいので、forEach を使ってトリガーの数だけループさせます。
2のデータ属性で取得した値も、扱いやすいようにオブジェクトとして格納しておきましょう。

const countUpTargets = document.querySelectorAll('[data-countup-target]');

countUpTargets.forEach( target =>{
	const countElement = {
		from: target.dataset.from,
		to: target.dataset.to
	}
})

続いて、gsap.to() を使って、具体的な動きを指定しましょう。
GSAPでは、第1引数には対象とする要素、第2引数にはプロパティと値を指定します。

  • GSAPアニメーションの具体例
    下記の場合、第1引数には’.target’を持つ要素を指定し、第2引数にはxプロパティに50、durationプロパティに2を指定しています。

    // '.target'を持つ要素を右に50px、2秒かけて移動させる
    gsap.to('.target', {
    	x: 50,
    	duration: 2,
    })
    

    scrollTriggerでアニメーションの開始位置を指定することも可能です。startプロパティには、トリガー要素のどの位置が画面のどの位置に来たらアニメーションを開始するかを指定します。

    // '.target'を持つ要素の中心(1つ目のcenter)が画面の中心(2つ目のcenter)に来たら、右に50px移動させる
    gsap.to('.target', {
    	x: 50,
    	scrollTrigger: {
    		trigger: '.target',
    		start: 'center center',
    	}
    })
    

今回の場合、data属性で指定した開始値から終了値までをカウントさせたいので、第1引数にnumberElement、第2引数にcountプロパティを指定します。
countUpTriggerをトリガーとして、要素の上部が画面の中央に来たら一斉にアニメーションが開始されます。

const numberElement = {
	count: countElement.from
}                                                                                                                                                                                                ;
gsap.to(numberElement, { // アニメーションさせたい要素(numberElement)
	count: countElement.to, // 終了値
	duration: 2, // アニメーションの時間(秒)
	ease: "power4.out", // イージングの種類
	scrollTrigger: {
		trigger: countUpTrigger, // トリガーとなる要素
		start: 'top center', // トリガーの開始位置
	}
})

最後に、コールバックを指定します。onUpdateは、アニメーション中に数字が更新されるたび(1秒間に約60回)に実行される関数です。GSAPは裏側で変数の値を書き換えるだけなので、そのままでは画面上の表示は変わりません。
そのため、onUpdateを使って、更新された最新の数字を target.textContent にその都度上書きしてあげる必要があります。

また、GSAPは滑らかに動かすために小数の状態で計算を進めます。そのまま表示すると「1.2345…」のように表示されてしまうため、Math.floor(または Math.trunc)を使って整数に整えてから画面に出しましょう。

onUpdate:()=>{
	countUpTarget.textContent = Math.floor(numberElement.count)                                                                                                                                                               ;
}
  • Math.floorとは
    引数として与えられた数値以下の最大の整数を返すメソッドです。
    例えば、Math.floor(2.7)は2を返します。

ちなみに、最後のonUpdateにて toLocaleString()を追加することで、数字をカンマ区切りにすることもできます。

countUpTarget.textContent = Math.floor(numberElement.count).toLocaleString()                                                                   ;
// 2,026

完成!

完成したアニメーションはこちら。

おわりに

いかがでしたか。GSAPを用いることで、スクロール位置に応じたアニメーションを簡単に実装することができます。
ぜひ皆さんのサイトでも取り入れてみてくださいね。

Category | Blog
Tag |
Author | Chiho Rokukawa / 43views

Company information

〒650-0024
神戸市中央区海岸通5 商船三井ビルディング4F

Contact us

WEBに関するお問い合わせは
078-977-8760 (10:00 - 18:00)