search
LoginSignup
59

More than 3 years have passed since last update.

posted at

updated at

数字のカウントアップを良い感じのアニメーションで実装したい

インフォグラフィックなどで、数字をカウントアップしたくなったときに役に立つかもしれないメモです。↓こんな感じにしたい。

count.gif

サンプルに使っている共通の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

index.html
<!-- Google Fontsから読み込み-->
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
index.css
.count {
  font-family: 'Roboto Mono', monospace;
}

See the Pen CountUp Animation monospace by noplan1989 (@noplan1989) on CodePen.

だいたい良い感じになりました。
現場からは以上です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
59