【ポモドーロタイマーを作ろうVanillaJS編②】~カウントダウン機能実装①~
前回要件定義を行ったので
今回はそれに従い、まずはVanilla JSで基本の動きを実装しました。
※最終的にはReact/Reduxにリプレイスしますが
JavaScriptの勉強も兼ねてまずはVanilla JSで書くことにしました。
表示領域の作成とDOM操作
まずは、index.htmlの作成から。
機能の実装を優先させたいので、一旦下記のような
必要最低限の項目のみ作成します。
※ここではCSSは割愛します。すみません!
<div class="container"> <div id="timer">25:00</div> <p id="timeState">WORK</p> <div class="controls"> <button class="btn" id="start">START</button> <button class="btn" id="stop">STOP</button> <button class="btn" id="reset">RESET</button> </div> <div> <p id="cycle">1/4</p> </div> </div>
カウントダウンの実装
基本的な考え方は以下の通り。
【残り時間】=【設定した作業時間】ー【経過時間】
※残り時間をtimer領域に表示
この【残り時間】の取得をsetTimeoutを使って1秒ごとに実行・描画を行うことで
画面上でカウントダウンされているように見える。
また、【経過時間】の取得は、Date.nowメソッドを用いて次のように計算する
【経過時間】=【①現在時刻】ー【②STARTボタンをクリックした時刻】
Date.now()メソッドは、既定時刻からの経過時間をミリ秒単位で取得するので
【残り時間】を計算する際は、作業時間をミリ秒単位に変換する必要がある。
以上を踏まえてコードを書くと
function countDown() { const remainigTime = (workTime * 60 *1000) - (Date.now() - startTime); // 0になるまではカウントダウンを繰り返す // 0より小さくなった後は別の処理を行うためif文で条件分岐しておく if ( remainigTime > 0 ) { // カウントダウンを止めるために必要なsetTimeoutの戻り値をtimeoutIdへ代入 timeoutId = setTimeout(() => { countDown(); }, 1000); } //STARTボタンをクリックした時刻をstartTimeとして取得 start.addEventListener('click', () => { startTime = Date.now(); countDown(); });
これで、設定した時間から1秒ごとにカウントダウンが実行される。
この記述ではミリ秒表記なので、見やすくするために単位の変換を行う。
ミリ秒を【○○(分):○○(秒)】の形式へ編集し描画
//取得したremainigTime(ミリ秒)から分と秒を計算 const restMin = String(Math.floor((remainigTime / 1000 / 60) % 60)).padStart(2, '0'); const restSec = String(Math.floor((remainigTime / 1000) % 60)).padStart(2, '0'); timer.textContent = `${restMin}:${restSec}`;
Math.floor:引数として与えた数以下の最大の整数を返す。(小数点以下切り捨て)
String:Number型をString型へ変換
padStart:Stringオブジェクトのメソッド。
結果の文字列が指定した長さになるように、
現在の文字列を他の文字列で (必要に応じて繰り返して) 延長する。
延長は、現在の文字列の先頭から適用される。
→分もしくは秒が一桁の時に、先頭に0を付けて二桁に揃える。
最後にDOM操作で取得した値を描画する。
まずは基本の動きの実装まで。
次回は、25分(作業)→5分(小休憩)→...→25分(作業)
→30分(長休憩)→最初へ戻る
というサイクルを自動的に行うための実装を。
↓↓私の師匠、もりけんさんの武骨日記。JavaScript問題集、要チェック