GSAPでカウントアップを実装【トリガー位置の調整も簡単】

コーダー
コーダー

デザインの指示書にカウントアップが書かれている…
実装方法調べてみたけど種類ありすぎて最適解が分からん

GSAP MAN
GSAP MAN

トリガー位置やease、秒数も自由に制御できるGSAPがおすすめだよ!

会社概要ページ等の「数字で見る◯◯」や円グラフの中に数字+%の数字をカウントアップさせるアニメーションをつけたいというご依頼を受けることが多いと思います

いざ検索窓に「カウントアップ JavaScript」と検索してみると素のJSを使った方法、jQueryのライブラリを使った方法などが結果にでてきます

できれば余計なライブラリを使わずに簡潔にかつ汎用性の高い方法で実装したいですよね

そこで今回はアニメーションライブラリGSAPとScrollTriggerを使用した方法をご提供します

実装イメージ

まずは実装イメージをご覧ください

スクロールすることで任意の位置に到達すると数字のカウントアップが始まります

See the Pen gsap カウントアップ by りょーすけ (@s_ryosuke_1242) on CodePen.

右側にあるscroller-startなどはマーカーで発火位置などを目視化してくれるScrollTriggerの機能です

HTML

html見た目はシンプルなのですが重要な点が一つあります

<div class="container">
    <!-- カウントアップする際のトリガー -->
    <p class="js-countUp-trigger">Trigger</p>
    <!-- カウントアップするテキスト -->
    <p class="js-countUp-target" data-from="0" data-to="2023">0</p>
</div>

5行目のデータ属性に注目してください

data-fromがカウントアップを始める際の数値

data-toがカウントアップの目標値です

つまり上の例の場合だと0から2023に数字をカウントアップします。

JavaScript上で数値を設定するよりかはHTMLにてデータ属性を使ってあげるほうがハードルは低いですよね。

いざというときにクライアント様側でも直感的に変更しやすいかと思います

CSS

cssは見た目を整える程度で特に注意点はありません

.container{
    width: 100%;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    padding-top: 200px;
    padding-bottom: 200px;
}
.js-countUp-trigger{
    font-size: 60px;
    margin-bottom: 300px;
}
.js-countUp-target{
    font-size: 60px;
}

JavaScript(GSAP)

いよいよ核となる部分。JavaScriptです

// カウントアップさせるターゲット
var countUpTrigger = document.querySelector('.js-countUp-trigger')
var countUpTarget = document.querySelector('.js-countUp-target')
// 連想(辞書)配列 数値情報
var elementDic = {
    from:countUpTarget.dataset.from,
    to:countUpTarget.dataset.to
}
// 連想(辞書)配列 gsapで制御させたい要素
var elementNum = {count:elementDic.from};
gsap.to(elementNum,{
    count:elementDic.to,//カウントさせる数値(終着点)
    duration:1,//カウントアップさせる秒数
    ease:'none',//デフォルトでpower(指数)がかかっている
    scrollTrigger:{
        trigger:countUpTrigger,// トリガーとなる要素の指定
        start:'top top',// トリガー位置の調整
        toggleActions:'play none none reverse',// 再度スクロールしても発火させる
        markers:true,// マーカーの表示
    },
    onUpdate:()=>{
        countUpTarget.textContent = Math.floor(elementNum.count);// 数字が変わる度にDOM要素に代入
        // countUpTarget.textContent = Math.floor(elementNum.count).toLocaleString();//コンマをつけたいとき
    }
})

2行目のvar countUpTrigger = document.querySelector(‘.js-countUp-trigger’)カウントアップ開始位置の目安となるトリガーの設定

3行目のvar countUpTarget = document.querySelector(‘.js-countUp-target)カウントアップさせる要素

それぞれターゲットとトリガーを取得した後に数値情報を含む連想配列を記述します

var elementDic = {
    from:countUpTarget.dataset.from,
    to:countUpTarget.dataset.to
}

次に10行目にてvar elementNum = {count:elementDic.from};同じく連想配列を記述します

これ何が便利なん?という疑問がでてきます

この後、使用するgsapのメソッド.to()にて大いに活躍します

gsapの基本単位Tweenのおさらいをしておきましょう

最初の引数に操作したい要素 その次の中括弧にアニメーションの内容を記述します

この操作したい要素ですが決してDOM要素のみでないといけないというルールはありません!

なんと…連想配列を代入することが可能となっております!この超優秀な恩恵を最大限に受けましょう

普段gsapのプロパティdurationeaseなど決まったものしか使えないのかと思いがちですが先程作った連想配列のkeyをプロパティにセットすることが可能です
これめちゃめちゃ便利なんですよね~お世話になってます!

あとはコメント文でも書いてあるように必要なプロパティを指定していきます

GSAPのコールバック関数onUpdate

最後に重要なポイントとして21行-24行目にて使用しているコールバック関数onUpdateがあります

これも重宝される関数で今回の場合で言うとelementNumのkey countの値がプログラム上でカウントアップする度に呼び出される関数です

22行目で使用されている.textContentはテキストを書き込むことが可能なメソッドです。これで見た目上にカウントアップされた数字をその都度反映させていきます

トリガー位置の調整

トリガーの位置調整させたいんだけど😇→超簡単です

17行目のstartプロパティで変えられます。startプロパティの見方はstart:’要素 画面’

例えば要素の中心が画面の中心に来た際に発火させたい場合はtop:’center center’,となります

まとめ

いかがだったでしょうか。

行数こそ短いわけではないですがトリガー位置や秒数などが簡単に変更を加えられる汎用性の高いコードになったかと思います

重要なポイントは

gsapのtargetには連想配列を指定してkeyに対応する値を変化させることができる
コールバック関数onUpdateで都度処理を行う

この記事が役に立った!と思っていただけた場合はぜひ拡散していただけますと嬉しいです!
次の記事もお楽しみに!