HTML + CSS + JSでエモいタイマー作り

ブラウザ上で動くタイマーを作る機会があったのでここで紹介します。

#つけた機能
- EnterキーでStart/Stop
- LキーでLapを表示
- Rキーでリセット(すべて0に戻す)

#使ったやつ
- HTML5
- CSS3
- JavaScript

あと**Bootstrap4**というフレームワークを使っています。
一応ですがここにCDNでBootstrap4を埋め込む方法を書いときます。`<head>`タグ内にコピペして貼り付けるだけでOKです。

```html:racetimer.html(Bootstrap4の埋め込み部分)
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
```

#コード
ざっとこんな感じです。ちなみにわかりやすさはカス中のカスです。ごめんなさい。

```html:racetimer.html(Body部分)
    <body style="background: #000;">
		<section class="passsec text-center container">
			<p>
				<div id="showArea" class="showRaceTime"></div>
			</p>
			<br>
			<p>
				<ul id="showLapArea" class="showLap">
				</ul>
			</p>
		</section>
	</body>
```

```html:racetimer.html(Javascriptの部分)
<script>
    //keydown code
	document.onkeydown = keydown;
	let flag = 0; //flag 0 -> not running, 1 -> running
	function keydown(){
		if(event.key == "Enter" && flag == 0){
			start();
		}
		else if(event.key == "Enter" && flag == 1){
			stop();
		}
        else if(event.key == "r"){
			reset();
		}
		else if(event.key == "l" && flag == 1){
			lap();
		}
	}
	//keydown end
	//addzero code
	function addzero(num){
		if(num < 10){
			ret = "0" + num;
			return ret;
		} else {
			return num;
		}
	}
	//addzero end
	//passsec code
	var passSec,passMsec,passMin,lapnum;
	
	passMsec = 0;
	passSec = 0;
	passMin = 0;
	lapnum = 0;
	var defaultmsg = "00:00:00";
	var defaultlap = "LAP0" + "&nbsp;&nbsp;" + "/" + "&nbsp;&nbsp;" + "00:00:00"
	
	document.getElementById("showArea").innerHTML = defaultmsg;
	function showSec(){
		passMsec++;
		
		if(passMsec > 99){
			passMsec = 0;
			passSec++;
		}
		if(passSec > 59){
			passSec = 0;
			passMin++;
		}
		
		var msg = addzero(passMin) + ":" + addzero(passSec) + ":" + addzero(passMsec);
		
		document.getElementById("showArea").innerHTML = msg;
	}
		
	function start(){
		timer = setInterval('showSec()',10);
		
		flag = 1;
	}
	
	function stop(){
		clearInterval(timer);
		
		flag = 0;
	}
	
	function reset(){
		passSec = 0;
		passMsec = 0;
		passMin = 0;
		lapnum = 0;
		
		var resetlap = "LAP" + lapnum + "&nbsp;&nbsp;" + "/" + "&nbsp;&nbsp;" + addzero(passMin) + ":" + addzero(passSec) + ":" + addzero(passMsec);
			
		clearInterval(timer);
		
		document.getElementById("showArea").innerHTML = defaultmsg;
		document.getElementById("showLapArea").innerHTML = "";
			
		flag = 0;
	}

	function lap(){
		lapnum++;
		var laptime = "LAP" + lapnum + "&nbsp;&nbsp;" + "/" + "&nbsp;&nbsp;" + addzero(passMin) + ":" + addzero(passSec) + ":" + addzero(passMsec);
		
		var lapArea = document.getElementById("showLapArea");
		var makeli = document.createElement("li");
	
        makeli.innerHTML = laptime;
        lapArea.appendChild(makeli);
	}
	//passsec end
</script>
```

```css:racetimer.css
li{
	list-style: none;
}

.passsec{
	padding-top: 40px;
	padding-bottom: 20px;
	padding-right: 20px;
	padding-left: 20px;
}
.showRaceTime{
	font-size: 200px;
	color: #ff0;
	text-shadow: 0 0 20px #cc0,0 0 20px #cc0;
}
.showLap{
	font-size: 30px;
	color: #ff0;
}
```
で、こんなのが出来ました。

<p data-height="455" data-theme-id="dark" data-slug-hash="eLopLw" data-default-tab="result" data-user="mrmcodepen" data-pen-title="timerrrrr" class="codepen">See the Pen <a href="https://codepen.io/mrmcodepen/pen/eLopLw/">timerrrrr</a> by まりも (<a href="https://codepen.io/mrmcodepen">@mrmcodepen</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

##それぞれの関数の解説的な

- `keydown`関数

ただの押されたキーを取得、判断してどの関数を実行するか決める関数です。

- `addzero`関数
 
数字がひと桁になったら先頭に0を加えるってだけです。
例えば5だったら05ってして表示させる、とか。

- `showsec`関数

実行される度に変数`passMsec`をインクリメントし、そいつを`分:秒:ミリ秒`に変えて表示させる関数です。`innerHTML`を使って該当部分にねじ込んでます。

- `start`関数

すべてのはじまりです。`showsec`関数を`setInterval()`で10msおきに実行させています。つまり、10msおきに変数`passMsec`がインクリメントされているわけです。

- `stop`関数

`clearInterval()`でインターバルを止めています。

- `reset`関数

言葉の通りすべてを0に返し、タイマーを停止させます。また、ラップの表示もすべてなくなります。

- `lap`関数

ラップを取得して表示させています。原理は簡単で、現在の分秒ミリ秒を取得してるだけです。
変数`lapnum`をインクリメントさせることでラップの回数を数えています。

##詰まった所
- タイマー稼働中にEnterキーを再度押すとカウントが加速する

「タイマー」とは？(哲学)
ということでちゃんと直しました。

```javascript:racetimer.htmlのJS部分から抜粋
	document.onkeydown = keydown;
	let flag = 0; //flag 0 -> not running, 1 -> running
	function keydown(){
		if(event.key == "Enter" && flag == 0){
			start();
		}
		else if(event.key == "Enter" && flag == 1){
			stop();
		}
        else if(event.key == "r"){
			reset();
		}
		else if(event.key == "l" && flag == 1){
			lap();
		}
	}
```

変数`flag`でタイマーが動いてるか否かの状態を表すようにしたら動きました。
このフラグは`start`関数が実行された時に立つ(= 1になる)、それ以外では折れる(= 0になる)ようになっています。詳しくは載っけたコード見て下さい。
例えば、 `start`関数はEnterキーが押される且つタイマーが動いてない状態の時にしか動作しないようにしてます。逆に`stop`関数はEnterキーが押される且つタイマーが動いてる状態の時にしか動作しないようにしてます。

- 変数名のダサさ・コードの統一性のなさ

うるせ〜〜〜〜〜！！！！！
知らね〜〜〜〜〜〜！！！！！！

##課題

- ラップの無限生成

Lキー押しまくることでラップが無限に表示されてしまうので、ある程度いったら更新するとかなんらかの処理を入れたいと思います。

#補足

フォントを変えるともっとエモくなります。
![Screenshot from 2018-09-22 22-12-37.png](https://qiita-image-store.s3.amazonaws.com/0/253550/5b56ca09-6fa6-5ee1-4dc0-b5fe4f11f0f7.png)
めっちゃそれっぽくなりました。ちなみにこのフォントは**DSEG**というフリーフォントを使用しています。[ここ](https://www.keshikan.net/fonts.html)からダウンロード出来ます。