JavaScriptには日付や時刻を取得するための機能が用意されています。その際に使われるのがDateオブジェクトです。

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>

アナログ時計の見た目は画像ではなく、HTMLとCSSで作ります。

spanタグがいくつか用意されていますが、クラス名「clock-hour, clock-min, clock-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()」が付与されています。このtransformの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オブジェクトは、さまざまなプログラムで応用できるため、覚えておくと良いでしょう。

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

JavaScriptの基本をおさらい