始めに
カウントアップのアニメーションは調べたらいくつかありましたが、最初はシャッフルされていて、1つずつ数字が確定するようなアニメーションは見つからなかったので記事にしました。(調べ方が悪いだけの可能性もありますが(汗))
以下にサンプルを載せます。データ周りが結構ややこしくなるかと思ったのですが、別に桁ごとにデータを持たなくても実装できたのでそこまで複雑ではありませんでした。
See the Pen 1つずつ数字が確定するサンプル by wintyo (@wintyo) on CodePen.
実装方法
桁数を取得する
最初にランダムに表示する桁数を目標の値から取得する必要があります。ネイティブで実装されていたら楽でしたが、なかったのでメソッド化します。
/**
* 桁数を取得する
* @param {number} number - 数値
* @returns {number} - 桁数
*/
function getDigits(number) {
// 0の場合は1桁を返す
if (number === 0) {
return 1;
}
let digits = 0;
while (number >= 1) {
number /= 10;
digits += 1;
}
return digits;
}
ランダムに数字を表示する
まずはシャッフル状態のアニメーションを作ります。アニメーションと言っても、ただintervalを使って表示する数字を差し替えているだけです。単純にランダムにするなら1回の乱数でいいですが、一桁ずつ確定していくことを踏まえて0~9の乱数を各桁ごと行います。各桁を算出できたら後は足し合わせます。各桁を上手く足せるようにべき乗を使用しています。
まとめると以下のようになります。今回は実装を楽するためにlodashのtimesとpadStartを使用しています。
const value = 2048;
const digits = getDigits(value);
window.setInterval(() => {
// 各桁の数値を算出する
const numbers = _.times(digits).map(() => {
return Math.floor(10 * Math.random());
});
// 足し合わせる
const displayValue = numbers.reduce((accumulator, number, index) => accumulator + (10 ** index) * number);
// 0詰めで表示させる
countElement.innerHTML = _.padStart(String(displayValue), digits, '0');
});
下の桁から確定していく
後は各桁の数値を算出する場所で表示したい値を出すか乱数を出すか場合分けをしたらいいです。
const value = 2048;
const digits = getDigits(value);
let fixDigits = 1; // 1桁目だけ数字を出す
window.setInterval(() => {
// 各桁の数値を算出する
const numbers = _.times(digits).map((index) => {
// 固定したい桁の場合は最終値を返す
if (index < fixDigits) {
return Math.floor(value / (10 ** index)) % 10;
}
return Math.floor(10 * Math.random());
});
// 省略
});
イベントをつなぎあわせる
最後にsetTimeoutを使ってfixDigitsのところをカウントアップしていき、最後の桁までたどり着いたらintervalを止めて完成です。
終わりに
そもそも言葉がわからないというのもありますが、今回のようなアニメーションは探しても見つからなかったので記事にしました。数字の表示は他にもいろいろあるようで、リンクを貼っておくので興味があればそちらも参考にしてみるといいかもしれません。