7日目のゴールと今日やること
7日目のテーマは
「タイマー & ストップウォッチ中級編の総仕上げとして、“設計を理解し、応用できる状態”になること」
です。
ここまでであなたは、
- setInterval / setTimeout の役割
- Date.now() を使った正確な時間管理
- 開始 / 停止 / 一時停止 / 再開 / リセット
- ミリ秒表示
- 多重起動防止(状態管理)
- 複数タイマーの同時管理
といった“時間アプリの本質”をすべて体験しました。
7日目はこれらをまとめて、
- 時間アプリの「共通構造」を理解する
- 状態管理を軸にした設計を言語化する
- setTimeout と setInterval の使い分けを整理する
- 自分で応用できるように「設計図」を作る
という、中級者としての視点を身につけます。
時間アプリの「共通構造」を理解する
時間アプリはすべて「3つの柱」でできている
ストップウォッチ
カウントダウン
複数タイマー
ポモドーロタイマー
アラーム
これらは見た目が違っても、
内部構造はほぼ同じです。
その「3つの柱」がこちら。
- 時間の計算ロジック
- 繰り返し処理(setInterval)
- 状態管理(running / paused / stopped)
この3つが揃えば、
どんな時間アプリでも作れます。
深掘り:時間の計算は「差分」で行う
時間アプリの本質は、
“今の時刻と基準時刻の差を取る”
という一点にあります。
ストップウォッチ
→ 経過時間 = (今の時刻 – startTime) + 過去の累積時間
カウントダウン
→ 残り時間 = endTime – 今の時刻
複数タイマー
→ タイマーごとに上記を計算するだけ
この「差分の考え方」を理解していると、
どんな時間アプリでも迷わなくなります。
setInterval と setTimeout の使い分けを整理する
setInterval の役割
setInterval は
“一定間隔で update を呼び続けるエンジン”
です。
ストップウォッチ → 0.01秒ごとに経過時間を更新
カウントダウン → 0.01秒ごとに残り時間を更新
複数タイマー → タイマーごとに update を呼ぶ
つまり、
時間アプリの本体ロジックは setInterval が担当
します。
setTimeout の役割
setTimeout は
“単発の遅延処理”
に向いています。
例えば、
- 終了時の点滅演出
- 3 → 2 → 1 → START のカウントダウン
- ボタンの一時的な無効化
- アニメーションの間隔調整
など、
「一回だけ遅らせたい」
という場面で使います。
深掘り:setTimeout の再帰は「回数付きの繰り返し」
setTimeout を再帰的に呼ぶと、
function blink(n) {
if (n <= 0) return;
element.classList.toggle("blink");
setTimeout(() => blink(n - 1), 200);
}
JavaScriptこのように
“回数 × 間隔”
の繰り返しが作れます。
setInterval では難しい制御なので、
中級者はこの使い分けを自然に行います。
状態管理が「多重起動防止」の核心
状態管理とは?
タイマーアプリは、
ユーザーの操作によって状態が変わります。
stopped
running
paused
この3つの状態を
文字列で管理する
のが最もシンプルで強力です。
状態による操作制御
例:start の場合
function start() {
if (state === "running") return; // 多重起動防止
if (state === "stopped") {
// 初回スタートの処理
}
if (state === "paused") {
// 再開の処理
}
}
JavaScript例:pause の場合
function pause() {
if (state !== "running") return;
// 停止処理
}
JavaScript深掘り:状態管理は「アプリの安全装置」
状態管理がしっかりしていると、
- start の連打で暴走しない
- pause の連打でバグらない
- reset の途中で変な動きにならない
- 複数タイマーでも破綻しない
という“安定したアプリ”になります。
時間アプリの「設計図」を作る
設計図の構造
時間アプリは、
次の 5 つの関数を軸に設計すると美しくまとまります。
- start
- update
- pause
- resume
- reset
これに加えて、
- 時間フォーマット関数(formatTime)
- 表示更新関数(renderTime)
- 状態管理(state)
- タイマーID管理(timerId)
を組み合わせると、
どんな時間アプリでも作れます。
例:ストップウォッチの設計図(要点)
let startTime = 0;
let elapsedBefore = 0;
let timerId = null;
let state = "stopped";
function start() {
if (state === "running") return;
if (state === "stopped") elapsedBefore = 0;
startTime = Date.now();
timerId = setInterval(update, 10);
state = "running";
}
function update() {
const now = Date.now();
const elapsed = elapsedBefore + (now - startTime);
renderTime(elapsed);
}
function pause() {
if (state !== "running") return;
elapsedBefore += Date.now() - startTime;
clearInterval(timerId);
state = "paused";
}
function resume() {
if (state !== "paused") return;
startTime = Date.now();
timerId = setInterval(update, 10);
state = "running";
}
function reset() {
clearInterval(timerId);
elapsedBefore = 0;
state = "stopped";
renderTime(0);
}
JavaScript深掘り:この設計図は「どんな時間アプリにも応用できる」
カウントダウンなら
elapsed → remaining に変わるだけ。
複数タイマーなら
この設計図を「タイマーごとに持つ」だけ。
ポモドーロなら
25分 → 5分 → 25分 → 5分
と「複数のカウントダウンを連結」するだけ。
setTimeout を使った「終了演出」を仕上げる
例:終了時に 3 回点滅
function finishEffect() {
let count = 3;
function blink() {
timeDisplay.classList.toggle("blink");
count--;
if (count > 0) {
setTimeout(blink, 200);
}
}
blink();
}
JavaScriptCSS
.blink {
opacity: 0.2;
}
深掘り:演出は「ロジックと分離」する
時間計算ロジックと
UI 演出は完全に分けることで、
- バグが減る
- コードが読みやすくなる
- 演出を自由に変えられる
というメリットがあります。
今日いちばん深く理解してほしいこと
7日目の本質は、
「時間アプリはすべて同じ構造で作れる」
という理解です。
その構造とは、
- 時間の差分計算
- setInterval による繰り返し
- 状態管理による制御
- UI は状態の写し
- setTimeout は演出用
という、
中級者としての“設計の視点”です。
ここまで理解できたあなたは、
もう「時間アプリを作れる人」ではなく、
“時間アプリを設計できる人”です。
次のステップとしては、
- ポモドーロタイマー
- マルチアラーム
- ストップウォッチ+ラップ記録の保存
- タイマーのプリセット管理
- UI のアニメーション強化
など、
あなたのアイデア次第でいくらでも発展できます。
ここまで本当に素晴らしい成長でした。

