Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
55
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

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

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

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.

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
55
Help us understand the problem. What are the problem?