インフォグラフィックなどで、数字をカウントアップしたくなったときに役に立つかもしれないメモです。↓こんな感じにしたい。
サンプルに使っている共通のHTML
<div class="container">
<p id="count" data-from="0" data-to="4096">0</p>
<button id="button">Start!</button>
</div>
setIntervalでカウントアップ
まずは素直にsetIntervalで実装してみます。一応カウントアップはできていますが、なんだか無味乾燥な印象を受けますね。
const DURATION = 3600
const el = {
count: document.getElementById('count'),
button: document.getElementById('button')
}
el.button.addEventListener('click', e => {
const from = parseInt(el.count.dataset.from, 10)
const to = parseInt(el.count.dataset.to, 10)
const startTime = Date.now()
const timer = setInterval(() => {
const elapsedTime = Date.now() - startTime
const progress = elapsedTime / DURATION
if (progress < 1) {
el.count.textContent = Math.floor(from + progress * (to - from))
} else {
el.count.textContent = to
clearInterval(timer)
}
}, 16)
})
See the Pen CountUp Animation setInterval by noplan1989 (@noplan1989) on CodePen.
動きに緩急をつける
setIntervalでは動きが単調なので緩急をつけていきます。
アニメーションに緩急をつけるには、Tween系のライブラリを使ってイージングを効かせるのが手っ取り早いと思うので、今回はTweenMaxを選びました。
TweenMaxは、要素のプロパティだけでなく、通常のオブジェクトに対しても使えるので、数字のカウントアップに適用します。イージングのおかげで緩急がついて、カウントアップに血が通った気がしますね。
この例ではInOut系のイージングを選びましたが、ちゃちゃっと見せたいときはOut系のイージングの方がいいかもです。
const DURATION = 3.6
const el = {
count: document.getElementById('count'),
button: document.getElementById('button')
}
el.button.addEventListener('click', e => {
const from = parseInt(el.count.dataset.from, 10)
const to = parseInt(el.count.dataset.to, 10)
let obj = {count: from}
TweenMax.to(obj, DURATION, {
count: to,
ease: Power3.easeInOut,
onUpdate: () => {
el.count.textContent = Math.floor(obj.count)
}
})
})
See the Pen CountUp Animation TweenMax by noplan1989 (@noplan1989) on CodePen.
フォントを等幅にする
スピードに緩急はつきましたが、数字がカタカタしているのが気になるかもしれません。プロポーショナルフォントの場合、フォントの幅がそれぞれ違うので、どうしてもカタカタしてしまいます。
デザインが許すのであれば等幅のフォントに変更してしまいましょう。google fontsにも色々あります。
https://fonts.google.com/?category=Monospace
<!-- Google Fontsから読み込み-->
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
.count {
font-family: 'Roboto Mono', monospace;
}
See the Pen CountUp Animation monospace by noplan1989 (@noplan1989) on CodePen.
だいたい良い感じになりました。
現場からは以上です。