CommentOut

【Javascript】数字がランダムにシャッフルされながら表示するやつ 【Javascript】数字がランダムにシャッフルされながら表示するやつ

【Javascript】数字がランダムにシャッフルされながら表示するやつ

公開日:  最終更新日:

「数字がランダムにシャッフルされながら表示するやつ」
本当はちゃんとした名前があるんだろうけど、なんて言うのかな?わかんない
でも、作ってみたので、紹介します。

とりあえず、サンプルを見て欲しい。「あー!それね!」ってなるから

See the Pen
数字がランダムな文字列から現れるFixed
by Uilou (@uilou754)
on CodePen.0

今回はこれの作り方を説明します。

ボタンクリックで指定桁数のランダムな数字を取得する

まず、ボタンクリックで指定した桁数のランダムな数字を取得できるようにします。

See the Pen
数字がランダムな文字列から現れる01
by Uilou (@uilou754)
on CodePen.0

以下がボタンクリックと数字を表示するスクリプトです。

// ボタンクリックイベント
$('button[name^="change_number"]').on('click', function() {
	// 10桁のランダムな数字を取得し、表示
	$('input[name^="dist_number"]').val(generateRandomNumber(10).toString());
});

キモとなる指定した桁数の数字を取得する部分は、generateRandomNumberという関数化しており、引数に10を入れています。
10桁の数字を取ってくるってことです。

関数の中身は以下の通りです。

// 指定桁数のランダムな数字を取得する
function generateRandomNumber(digits) {
	const min = Math.pow(10, digits - 1);
	const max = Math.pow(10, digits) - 1;
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

引数のdigitsが桁数で、Math.powは累乗する関数です。

例えば、digitsが5(5桁)の場合
Math.pow(10, digits – 1)は、10×10×10×10となるため、10000がminに入ります。
Math.pow(10, digits) – 1は、10×10×10×10×10-1となるため、99999がmaxに入ります。
どうですか?ちゃんと5桁の数字の範囲にminとmaxが収まっているでしょう?

そして、Math.random()を用いて、この数字範囲で乱数を取得しています。

クリックされるたびに、この関数が呼び出され、毎回ランダムな数字が表示されるという仕組みになっています。

1クリックで10回ランダムな数字が表示されるようにする

次に、ランダムな数字がバラバラ切り替わっているように見せなければいけません。
しかし、通常のアルゴリズムはイベントドリブンなので、1クリックイベントに対して、1回しか処理されません。
そこで、繰り返し処理のsetInterval()の出番です。

See the Pen
数字がランダムな文字列から現れる02
by Uilou (@uilou754)
on CodePen.0

setIntervalを止める方法

setInteval関数自体は指定されたミリ秒ごとに処理を実行してくれる便利な関数なので、よくご存じだと思いますが、setIntervalの停止方法はご存じでしょうか?

setIntervalを行った時、戻り値としてIDが返されます。
このIDをclearInterval関数に引数で渡してやることで、繰り返し処理を止める事ができます。

var cnt = 10;
const intervalId = setInterval(function() {
	// コンソール出力
	console.log(cnt);

	// カウントが0以下になったら繰り返し処理を停止する
	if (cnt <= 0) clearInterval(intervalId);
	cnt -= 1;
}, 200);

そのため、上記のサンプルではsetInterval関数の中でカウントを行い、10回動作した後、clearIntervalを行うようにしています。

なので、10回ランダムな数字を表示するには、以下のコードを記述します。

$('button[name^="change_number"]').on('click', function() {
	var cnt = 10;
	const intervalId = setInterval(function() {
		// 10桁のランダムな数字を取得して、表示する
		$('input[name^="dist_number"]').val(generateRandomNumber(10));

		// カウントが0以下になったら繰り返し処理を停止する
		if (cnt <= 0) clearInterval(intervalId);
		cnt -= 1;
	}, 200);
});

ランダムな数字の桁数を徐々に減らしていく

ここまでで、setIntervalを止めることができるようになったら、ランダムな数字の桁数を徐々に減らしていきます。
超簡単です。

$('button[name^="change_number"]').on('click', function() {
	var cnt = 10;
	const intervalId = setInterval(function() {
		// 10桁のランダムな数字を取得して、表示する
		$('input[name^="dist_number"]').val(generateRandomNumber(cnt));

		// カウントが0以下になったら繰り返し処理を停止する
		if (cnt <= 0) clearInterval(intervalId);
		cnt -= 1;
	}, 200);
});

generateRandomNumber関数に代入していた”10″(10桁の数字を得るため)を、10回の繰り返し処理のために用意した変数”cnt”に変更します。

See the Pen
数字がランダムな文字列から現れる03
by Uilou (@uilou754)
on CodePen.0

そうすると、あら不思議!
変数”cnt”は、初期値に10が与えられ、繰り返し処理が1回実行されるたびに、cntが-1され、0になると繰り返し処理は停止します。

目標となる数字に徐々に切り替える

乱数の桁数が徐々に減っていくのはここまでで作りました。
次は指定された数字に徐々に切り替えていく処理です。
数字を入れ替えていくというのは、以下のようなことです。

指定桁数指定桁数の乱数目標数字表示数
1回目637656712345376567
2回目5467921234546792
3回目434971234513497
4回目37851234512785
5回目2291234512329
6回目161234512346
7回目01234512345

さて、どうやって作りましょうかね。
イメージとしては、最初に指定桁数の乱数を生成し、そこに右揃えで目標数字を上書きするイメージです。
そういう処理をするってことは、2つの数字を”数値”として持たせるのではなく、”文字列”として保持していた方が都合が良さそうですね。

そこで私、考えました。

  1. 指定桁数の乱数(randomNumber)を一度文字列に変換(randomNumberStr)
  2. 目標数字(targetNumber)も文字列に変換(targetNumberStr)
  3. targetNumberStrからrandomNumberStrの文字数分削除し、その後、randomNumberStrを連結する

上記をJavascriptにすると、こんな感じです。

targetNumberStr.slice(0, targetNumberStr.length - randomNumberStr.length) + randomNumberStr;

で、これを動かすと、以下のサンプルのようになります。

See the Pen
数字がランダムな文字列から現れる04
by Uilou (@uilou754)
on CodePen.0

あとは桁数が減るのが早すぎるため、Digitsを毎回減らすのではなく、カウンタを作成し、10回実行されるたびに、桁数を1つ減らすなどの処理を行うと、一番最初のサンプルの動きとなります。

皆さんもぜひ使ってみてください!

宣伝
WordPressサイトのテンプレート編集やトラブル対応、バグ修正、簡単なJavascriptの作成(カルーセルやバリデーション等)など、小規模なスポット対応を受け付けております。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。

この記事を書いた人

uilou

uilou

プログラマー

基本的に、自分自身の備忘録のつもりでブログを書いています。 自分と同じ所で詰まった人の助けになれば良いかなと思います。 システムのリファクタリングを得意としており、バックエンド、フロントエンド、アプリケーション、SQLなど幅広い知識と経験があります。 広いだけでなく、知識をもっと深堀りしていきたいですね。