JavaScriptには、日付や時刻を取得するための機能が用意されています。
Dateオブジェクトを活用することで、時間の測定や作成時刻の保存ができます。

そこで今回は、Dateオブジェクトを用いてJavaScriptでアナログ時計を実装する方法を解説していきます。

デモ

今回は、このようなアナログ時計を作っていきます。

HTMLとCSSの準備

まずはHTMLとCSSの準備をしていきます。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Analog Clock</title>
<link rel="stylesheet" href="styles.css">
<script src='index.js'></script>
</head>
<body>
<div class="container">
  <h1>Analog clock</h1>
  <div class="edge-clock">
    <span class="clock-hour"></span>
    <span class="clock-min"></span>
    <span class="clock-sec"></span>
    <span class="clock-12">12</span>
    <span class="clock-3">3</span>
    <span class="clock-6">6</span>
    <span class="clock-9">9</span>
  </div>
</div>
</body>
</html>

spanタグがいくつか用意されています。
クラス名clock-hour・ clock-minclock-secは、それぞれ時針・分針・秒針になります。
クラス名clock-12, clock-3, clock-6, clock-9は時計の時刻を示す数字です。

CSS

html {
  font-size: 30px;
  color: white;
}

body,html {
  font-family: serif;
}

.container {
  margin: 0 auto;
  width: 400px;
}

h1 {
  color: navy;
}

.edge-clock {
  position: relative;
  width: 400px;
  height: 400px;
  border: 4px solid navy;
  background-color: red;
  border-radius: 50%;
}

.clock-12 {
  position: absolute;
  top: 3%;
  left: 45%;
}

.clock-3 {
  position: absolute;
  top: 43%;
  left: 90%;
}

.clock-6 {
  position: absolute;
  top: 87%;
  left: 47%;
}

.clock-9 {
  position: absolute;
  top: 43%;
  left: 3%;
}

.clock-hour {
  position: absolute;
  top: calc(50% - 150px);
  left: calc(50% - 5px);
  width: 10px;
  height: 150px;
  background: navy;
  transform-origin: bottom;
  transform: rotate(90deg);
}

.clock-min {
  position: absolute;
  top: calc(50% - 180px);
  left: calc(50% - 2px);
  width: 4px;
  height: 180px;
  background: white;
  transform-origin: bottom;
  transform: rotate(0deg);
}

.clock-sec {
  position: absolute;
  top: calc(50% - 200px);
  left: calc(50% - 1px);
  width: 2px;
  height: 200px;
  background: navy;
  transform-origin: bottom;
  transform: rotate(0deg);
}

.clock-hour, .clock-min, .clock-secのスタイルには、要素を回転するtransform: rotate()が付与されています。このrotateの中に回転させたい角度を指定することで、要素が回転された状態で表示されるようになります。

JavaScriptを実装していくと針は動くことになりますが、ここでは一旦初期に表示したい針の角度を指定することにします。

まずはここまでの記述で以下のように表示されることを確認します。

javascript-analogclock

時針が3、分針と秒針が12を指していることが分かります。先ほどのtransformに別の角度を指定すると表示が変わるため、好みで調整してください。

JavaScriptでアナログ時計を実装

HTMLとCSSの準備ができたら、JavaScriptに移っていきましょう。

全体のコード

function getElements() {
  const time = new Date();
  const hour = time.getHours();
  const minute = time.getMinutes();
  const second = time.getSeconds();

  const degreeHour = hour / 12 * 360;
  const degreeMin = minute / 60 * 360;
  const degreeSec = second / 60 * 360;

  const clockHour = document.getElementsByClassName('clock-hour')[0];
  const clockMin = document.getElementsByClassName('clock-min')[0];
  const clockSec = document.getElementsByClassName('clock-sec')[0];

  clockHour.style.setProperty('transform', `rotate(${degreeHour}deg)`);
  clockMin.style.setProperty('transform', `rotate(${degreeMin}deg)`);
  clockSec.style.setProperty('transform', `rotate(${degreeSec}deg)`);
}

setInterval(getElements, 10);

関数自体は1つだけです。アナログ時計の実装はシンプルな記述で済むことが分かります。
時・分・秒で現在時刻を取得し、それらの時刻を示す針をどの角度で動かしていくかを理解できれば難しくはありません。

それでは上から順番にコードを解説していきます。

現在の時・分・秒を取得する

冒頭に述べたように日付や時刻を取得するためのDateオブジェクトを使います。

const time = new Date();
const hour = time.getHours();
const minute = time.getMinutes();
const second = time.getSeconds();

はじめに、new Date()でDateオブジェクトを生成します。引数に何も入れなければ現在の日付と時刻でDateオブジェクトを作ることになります。

Dateオブジェクトには、年や月などへアクセスするためのメソッドが用意されています。
ここでは時計の時刻を構成している時・分・秒へのアクセスが必要なため、getHours(), getMinutes(), getSecounds()メソッドを用いて時刻を取得します。

以下を試してみると、実行している現在時間(Hour)が出力されるはずです。

const time = new Date();
const hour = time.getHours();
console.log(hour); // 15(15時の場合)

針の角度を計算する

上記で取得した時・分・秒をそれぞれ針の角度で表します。

const degreeHour = hour / 12 * 360;
const degreeMin = minute / 60 * 360;
const degreeSec = second / 60 * 360;

時間は「12(時針が通過する拠点数)」と「360(円の角度)」を掛けた値で割り、分数と秒数の場合はそれぞれ「60(分針と秒針が通過する拠点数)」と「360」を掛けた値で割ります。

このように計算すると、すべての針の示す角度を求めることができます。

現在時間の角度をスタイルに追加

上記で取得した要素に現在時刻を表す角度を指定します。

clockHour.style.setProperty('transform', `rotate(${degreeHour}deg)`);
clockMin.style.setProperty('transform', `rotate(${degreeMin}deg)`);
clockSec.style.setProperty('transform', `rotate(${degreeSec}deg)`);

スタイルを追加するためには、setPropertyメソッドを使用します。
要素.style.setProperty('プロパティ名', スタイル)と指定すると、要素に指定したスタイルが付与されます。

clockHour.style.setProperty('transform', `rotate(${degreeHour}deg)`)は、時針を現在の時間を示す角度に回転させるという意味です。
つまり、リアルタイムを表す角度に回転させるというスタイルになります。

分針・秒針も同様に行います。

タイマー処理を実行する

さいごに、上記で記述した関数を一定の時間ごとに実行させます。

setInterval(getElements, 10);

setInterval関数は、指定した時間ごとに処理を実行させるための関数で、setInterval(関数, 時間)と記述します。この場合は、0.01秒ごとにgetElements関数を繰り返すということになります。

秒針が1秒ずつ動けば問題ないため、時間を1000に設定しても良いでしょう。
CSSで設定した初期の針の角度から現在時刻の針の角度に変更されるまで1秒かかってしまうため、ここではあえて10を設定し関数の実行を早めています。

これでアナログ時計の実装が完了しました。

まとめ

今回は、アナログ時計の実装をしました。

アナログ時計の実装には、時間の取得と針を動かすことがポイントです。
特に、今回使用したDateオブジェクトは、さまざまなプログラムで応用できるため覚えておくと便利です。

ぜひ、好みの時計にアレンジして試してみてください。

アナログ時計の関連記事

データ型 -オブジェクト
変数名のルールと命名規則
Dateオブジェクトの作成