【JavaScript】シンプルな時計とカスタム可能な時計をGitHubPagesで公開してみた


# Webデジタル時計アプリ

二つのデジタル時計をJavaScriptで作成してみました。
- simple：ステップ少なくシンプルな秒単位のデジタル時計。約50ステップ
- custom：表示はシンプルですが、幾らかカスタマイズ可能なデジタル時計。約500ステップ

---

# デモ

https://kubo-4ka.github.io/clocks-js/


# ソース

https://github.com/kubo-4ka/clocks-js

---

##  simple時計の特徴
- 最小限の記述

##  simple時計の解説

```html
<!DOCTYPE html> <!-- HTML5文書であることを宣言 -->
<html lang="ja"> <!-- ページの言語を日本語に指定 -->
<head>
  <meta charset="UTF-8" /> <!-- 文字コードをUTF-8に設定（日本語など対応） -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- レスポンシブ対応（スマホでも拡大縮小しない） -->
  <title>時計</title> <!-- タブに表示されるタイトル -->
  <style>
    body {
      margin: 0; /* 余白なしで全画面表示 */
      background: black; /* 背景を黒に */
      color: white; /* 文字色を白に */
      font-family: sans-serif; /* 読みやすいフォントに */
      display: flex; /* Flexboxで中央寄せレイアウト */
      flex-direction: column; /* 縦方向に積む（時刻→日付） */
      justify-content: center; /* 縦方向中央揃え */
      align-items: center; /* 横方向中央揃え */
      height: 100vh; /* ビューポート全体の高さを使用 */
    }
    #time {
      font-size: 10vw; /* 画面幅に応じて大きなフォント */
    }
    #date {
      font-size: 5vw; /* 日付は少し小さめに */
    }
  </style>
</head>
<body>
  <div id="time">00:00:00</div> <!-- 初期表示用の時刻領域（秒まで） -->
  <div id="date">2025/03/31 MON</div> <!-- 初期表示用の日付・曜日 -->
  <script>
    function update() {
      const now = new Date(); // 現在日時を取得
      const time = now.toLocaleTimeString('ja-JP', { hour12: false }); // 24時間表記の時刻（例：13:45:22）
      const y = now.getFullYear(); // 年（例：2025）
      const m = String(now.getMonth()+1).padStart(2, '0'); // 月（0始まりなので+1し、2桁化）
      const d = String(now.getDate()).padStart(2, '0'); // 日（2桁化）
      const w = ['SUN','MON','TUE','WED','THU','FRI','SAT'][now.getDay()]; // 曜日（インデックスで配列から取得）

      document.getElementById('time').textContent = time; // 時刻を画面に表示
      document.getElementById('date').textContent = `${y}/${m}/${d} ${w}`; // 日付＋曜日を画面に表示
    }

    update(); // 初回の表示更新（読み込み直後）
    setInterval(update, 500); // 毎秒更新（0.5秒ごとにupdateを呼び出し）
  </script>
</body>
</html>
```

---

##  custom時計の特徴

-  **表示単位変更**：時:分、時:分:秒、ミリ秒まで切り替え可能
-  **背景色・文字色を自由に選択**（同色を防ぐ補色処理つき）
-  **フォント変更**（Web Safe Fonts 対応）
-  **文字サイズを20段階で調整可能**
-  **日付形式選択**（`YYYY/MM/DD`, `MM/DD`, `なし`など）
-  **曜日形式切替**（日本語「月」／英語「MON」／非表示）
-  **タイムゾーン切替**（JST/UTC/NYなど選択可）
-  **設定保存機能**（localStorageに保存／復元）
-  **「デフォルトに戻す」ボタンつき（localStorage削除）**
-  **画面タップでフルスクリーン切り替え**
-  **ハンバーガーメニューによる設定UI**

---

##  custom時計の使い方

1. `index.html` をブラウザで開くだけで使用できます
2. メニュー（左上）から表示を自由にカスタマイズ
3. スマホでもPCでもそのまま動作します

---

## custom時計のその他仕様

- 文字色と背景色が同一の場合、自動で文字色を補色に変更し、
  「背景と文字色が同一のため、文字色を変更しました」と通知されます
- 設定はローカルストレージに保存され、ブラウザを閉じても復元されます

---

## custom時計の技術スタック

- HTML / CSS / JavaScript（vanillaJS）のフロントエンドのみの構成
- GitHubpagesでホスト
- localStorage による永続化
- CSSトランジション／カスタム通知表示

---

## ファイル全体での責務分離（役割）

| ファイル | 役割 |
|---------|------|
| `index.html` | HTML構造とUI部品を定義（DOM）。 |
| `style.css` | 外観とレイアウトを整備（デザイン）。 |
| `script.js` | 時計更新・設定制御・保存処理など（ロジック）。 |

---
<details><summary>custom時計のhtmlについて</summary>

## htmlについて

| セレクタ / タグ | 役割・説明 |
|------------------|-------------|
| `<div id="timezoneIdDisplay">` | タイムゾーンID（例：Asia/Tokyo）を画面右上に表示。チェックボックスで非表示にもできる。 |
| `<div id="menu-button" class="hamburger">` | ハンバーガーメニューのトグルボタン。3本線が描かれ、クリックで設定パネルを表示/非表示。 |
| `<div id="menu-panel">` | 左側からスライドして表示される設定パネル本体。背景色や文字色、フォントなどを変更可能。 |
| `<input type="color" id="bgColorPicker">` | 背景色の選択に使うカラーピッカー。リアルタイムで背景が変化する。 |
| `<input type="color" id="textColorPicker">` | 文字色の選択に使うカラーピッカー。補色による自動修正ロジックあり。 |
| `<select id="timeFontSelect">` | 時刻フォントの選択肢（Web Safe Fonts）。選択肢とvalueが一致するよう工夫されている。 |
| `<select id="dateFontSelect">` | 日付フォントの選択肢。上記と同様の仕組み。 |
| `<input type="range" id="timeSizeRange">` | 時刻の文字サイズを調整するスライダー。1〜20の数値をvw単位で使用。 |
| `<input type="range" id="dateSizeRange">` | 日付の文字サイズ用スライダー。上記と同様。 |
| `<select id="dateFormatSelect">` | 日付の形式を選択。例：YYYY/MM/DD、MM/DD、表示なし など。 |
| `<select id="weekdayFormatSelect">` | 曜日表記の形式。日本語（例：月）、英語（MON）、非表示の切り替え。 |
| `<select id="timeUnitSelect">` | 表示形式を選択。時:分、時:分:秒、ミリ秒まで表示などを切り替え可能。 |
| `<select id="timezoneSelect">` | タイムゾーンの選択（JST, UTC, America/New_York など）。 |
| `<input type="checkbox" id="showTimezoneLabel">` | タイムゾーンの表示/非表示の切り替え。右上に表示される文字列を制御。 |
| `<button id="resetSettings">` | すべての設定をデフォルトにリセット。localStorage もクリアされる。 |
| `<div class="clock-container" onclick="toggleFullScreen()">` | 時計のメイン表示エリア。クリックでフルスクリーン表示に切り替え可能。 |
| `<div id="time" class="time">` | 時刻（例：14:23:56）を表示。フォントやサイズは動的に適用される。 |
| `<div id="date" class="date">` | 日付＋曜日を表示（例：2025/03/31 MON）。表示形式は選択式。 |
| `<div id="notification">` | 補色適用時などに控えめな通知を画面下に表示する要素。3秒で自動非表示。 |
| `<script src="script.js">` | アプリのロジック（時計更新、設定保存/復元、イベント処理など）を読み込み。 |

</details>

---

<details><summary>custom時計のjsについて</summary>

## jsについて

### 構造図（ざっくり）
```
+--------------------+
| グローバル変数群    |
+--------------------+
          |
+--------------------+
| ロジック関数群      | ← 時計更新 / 補色 / 通知表示など
+--------------------+
          |
+--------------------+
| 状態管理・適用      | ← 設定の取得・保存・反映
+--------------------+
          |
+--------------------+
| 初期化とイベント登録 |
+--------------------+
```


| セクション名 / 関数名 | 説明 |
|------------------------|------|
| `let dateFormat = "YYYY/MM/DD"` など | グローバル変数：日付形式、曜日形式、時間形式、タイムゾーン、コロン点滅管理などを定義。 |
| `getComplementaryColor(hexColor)` | 文字色と背景色が同じだった場合に補色を算出するための関数。`0xFFFFFF ^ 元の色` を使用して反転。 |
| `showNotification(message)` | 画面下にメッセージ（例：「文字色を変更しました」）を一時的に表示。CSSトランジションで3秒後に自動非表示。 |
| `updateClock()` | 現在時刻と日付を取得し、設定に従って整形して画面に表示。日本語／英語曜日も切替可。 |
| `toggleFullScreen()` | 時計表示部分をクリックしたとき、フルスクリーンのオン／オフを切り替える。 |
| `getSettings()` | 設定パネルから現在選択されている値（色、フォント、サイズ、形式など）をまとめて取得。 |
| `applySettings(settings)` | 指定された設定オブジェクトに従って、画面のスタイルを一括適用。localStorageへの保存と連動。<br>同色だった場合に補色を自動適用し、通知も表示。 |
| `updateClockLoop()` | 毎フレーム `requestAnimationFrame()` を使って時計を更新。コロン点滅やミリ秒にも対応。 |
| `window.addEventListener('DOMContentLoaded', ...)` | ページ読み込み時に初期化処理を実行：<br>保存された設定の復元、初期設定の適用、各種イベントリスナーの登録。 |
| `menuButton.addEventListener('click', ...)` | ハンバーガーメニューの開閉トグル処理。クラスの追加・削除で制御。 |
| `resetSettings` のイベントリスナー | デフォルト設定を適用し、保存されたローカル設定を削除（localStorageからクリア）。 |
| `document.addEventListener('click', ...)` | メニュー以外をクリックした場合に、メニューを自動的に閉じる処理。モバイルフレンドリー。 |

## script.js の全体構成・設計思想
JavaScriptファイルは、シンプルなHTMLページ上で動作するWeb時計アプリの中核であり、以下の4つの責務を分担して持っています：

### 1. データ定義と状態管理（変数定義）
```js
let dateFormat = "YYYY/MM/DD";
let weekdayFormat = "JP";
let timeUnit = "hms";
...
```
- アプリの表示形式や状態をグローバル変数として保持します
- タイムゾーンや日付・曜日形式、時刻の表記形式などが対象です
- コロンの点滅制御や、現在のタイムゾーンもここで管理されます

### 2. ロジック関数（純粋な処理系）
```js
function getComplementaryColor(hexColor) { ... }
function showNotification(message) { ... }
function updateClock() { ... }
```

- 見た目の変更や通知の表示など、「特定の目的を果たす関数群」です
- 補色変換や通知UIの表示、現在日時の取得とフォーマットなど
- updateClock() は画面更新の中心となる関数で、表示ロジックの核です

### 3. 設定の保存・反映（状態操作）
```js
function getSettings() { ... }
function applySettings(settings) { ... }
```

- 現在のユーザー設定を取得・適用・保存するロジックです
- カラーピッカーやセレクトボックスから値を取得し、画面スタイルや変数に反映します
- localStorage に保存され、次回読み込み時に自動で復元されます

### 4. 初期化処理とイベント登録（起動時・ユーザー操作）
```js
window.addEventListener('DOMContentLoaded', () => {
  ...
});
```

- DOMが読み込まれたら、初期設定やイベントリスナーを一括で登録
- ハンバーガーメニューの開閉処理、設定変更に応じた反映、デフォルト復元などを担当
- 同時に updateClockLoop() を呼び、リアルタイム表示を開始します

</details>

---

<details><summary>custom時計のcssについて</summary>

##  style.css の構成と役割

### ベーススタイル

| セレクタ | 説明 |
|----------|------|
| `body` | 全画面、黒背景、白文字、中央揃え、選択不可、スクロール防止。基本的なアプリの土台スタイル。 |
| `.clock-container` | 時計の時刻・日付を中央に配置するためのコンテナ。クリックでフルスクリーン化をトリガー。 |
| `.time`, `.date` | 時計のメイン表示部分。フォントやサイズは JavaScript 側で動的に設定される。 |

---

### ハンバーガーメニュー関連

| セレクタ | 説明 |
|----------|------|
| `.hamburger` | 左上に表示される3本線のメニューアイコン（縦に3本の `span`）。 |
| `.hamburger span` | ハンバーガー線1本ごとのスタイル（太さや色など）。 |
| `.hamburger.active span:nth-child(...)` | メニューが開かれているときに、ハンバーガーが×（バツ）に変形するアニメーション。 |

---

### メニュー表示（サイドパネル）

| セレクタ | 説明 |
|----------|------|
| `#menu-panel` | 左側からスライドして出てくる設定パネル本体。初期状態は `left: -100%`（非表示）。 |
| `#menu-panel.active` | 表示状態になった時 `left: 0` で画面内にスライド表示される。 |
| `.setting-group` | 設定UI（カラー、フォント、スライダーなど）のグループ単位のレイアウト。 |
| `.setting-group label` | 各設定項目のラベルテキストに使う。 |
| `.dark-select` | セレクトボックスの共通クラス。ダーク背景に合うよう調整。 |
| `.setting-group input[type=\"color\"]` | カラーピッカーの見た目（枠線や背景色）をダークテーマに統一。 |
| `.setting-group button` | 「デフォルトに戻す」などのボタンスタイル。ホバーで色が変わるように工夫。 |

---

### タイムゾーン表示

| セレクタ | 説明 |
|----------|------|
| `#timezoneIdDisplay` | 右上にタイムゾーンID（例：Asia/Tokyo）を控えめに表示。チェックで表示/非表示を切替可能。 |

---

### 通知バナー（メッセージ表示）

| セレクタ | 説明 |
|----------|------|
| `#notification` | 自動で消える控えめな通知エリア。画面下に表示され、補色変更などをユーザーに伝える。 |
| `#notification.show` | 表示時のスタイル。CSSトランジションでフェードイン・アウトするようになっている。 |

---

### その他の特性

- **すべてのカラー・フォントサイズは JavaScript 側で動的に上書きされる**よう設計されています
- **画面サイズへの自動対応**を前提に `vw`（画面幅に対する比率）を使用
- **スマホ環境向け**に、時計縦スクロール禁止・メニュースクロール可能対応など細かい配慮もあり

</details>

---