javascriptでアナログ時計を作成

今回はjavascriptでアナログ時計を作ってみました。

----

## なぜ作ったか

----

アナログ時計なので
時間周りの処理が必要なのでそこらへんの勉強になるのと、
あまりwebサイトではアナログ時計を見ないですが、サイトにあったら意外とお洒落かもと思って
作ってみました。

----

## 作るアナログ時計の完成イメージ

----

<img width="424" alt="スクリーンショット 2020-08-07 10.04.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163415/0903ac44-fa94-8747-624d-34d957889648.png">

----

基本的な丸型の時計です。

----

## コード

----

### html

----

まずはアナログ時計の元になるhtmlを書いていきます。
必要なhtmlはごく少量です。
大きく分けて、必要なのは

----

- 外枠
- 時針
- 分針
- 秒針
- 時間の文字

----

これだけです。

----

```html
<div class="c-clock"> // 外枠
  <span class="c-clock__hour"></span> <!-- 時計 -->
  <span class="c-clock__min"></span> <!-- 分針 -->
  <span class="c-clock__sec"></span> <!-- 秒針 -->
  <span class="c-clock__12">12</span> <!-- 時計文字 -->
  <span class="c-clock__3">3</span> <!-- 時計文字 -->
  <span class="c-clock__6">6</span> <!-- 時計文字 -->
  <span class="c-clock__9">9</span> <!-- 時計文字 -->
</div>
```

----

ちなみにbem記法で書いてるので気になる方はこちらも
https://qiita.com/w-tdon/items/2ede0122286f88db472f

----

### css

----

```css
.c-clock {
  position: relative;
  width: 400px;
  height: 400px;
  border: 1px solid #333;
  border-radius: 50%;
}
.c-clock__hour {
  position: absolute;
  top: calc(50% - 150px);
  left: calc(50% - 5px);
  width: 10px;
  height: 150px;
  background: #333;
  transform-origin: bottom;
}
.c-clock__min {
  position: absolute;
  top: calc(50% - 180px);
  left: calc(50% - 2px);
  width: 4px;
  height: 180px;
  background: #333;
  transform-origin: bottom;
}
.c-clock__sec {
  position: absolute;
  top: calc(50% - 200px);
  left: calc(50% - 1px);
  width: 2px;
  height: 200px;
  background: #ff0000;
  transform-origin: bottom;
}
.c-clock__12 {
  position: absolute;
  top: 10px;
  left: calc(50%);
  transform: translateX(-50%);
  font-size: 18px;
}
.c-clock__3 {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  font-size: 18px;
}
.c-clock__6 {
  position: absolute;
  bottom: 10px;
  left: calc(50%);
  transform: translateX(-50%);
  font-size: 18px;
}
.c-clock__9 {
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translateY(-50%);
  font-size: 18px;
}
```

----

- 外枠
  - width,height値を決め、border-radius: 50%で丸枠を作っています。

----

- 時針
  - 外枠にposition: relativeを仕込んでいるのでabsoluteを使い上下左右中央に配置しています。
  - top: 50%だと時針の高さ分ずれてしまうのでcalcを使い時針の高さ分引いてます。

----

- 分針
  - 分針も時針と同じです。

----

- 時間文字
  ここはwidth、heightを使ってないのでcalc(50% - ○px)とかして上下左右中央に配置できません。
  なのでtop: 50%;を設定し、transform: translateY(-50%)で要素の表示位置を要素の半分の大きさ分、上にずらします。

----

### js

----

```js
setInterval(() => {
  // 現在時間の取得
  const now = new Date();
  const h = now.getHours();
  const m = now.getMinutes();
  const s = now.getSeconds();

  // 時、分、秒を元に角度を計算
  const degH = h * (360 / 12) + m * (360 / 12 / 60);
  const degM = m * (360 / 60);
  const degS = s * (360 / 60);

  // 各要素を取得
  const elementH = document.querySelector(".c-clock__hour");
  const elementM = document.querySelector(".c-clock__min");
  const elementS = document.querySelector(".c-clock__sec");

  // styleを追加
  elementH.style.transform = `rotate(${degH}deg)`;
  elementM.style.transform = `rotate(${degM}deg)`;
  elementS.style.transform = `rotate(${degS}deg)`;
}, 10);
```

----

まず、タイマー処理でよく使われるsetIntervalを使用します。
setInterval関数は一定時間ごとに繰り返し処理を行う関数です。
似たものでsetTimeoutがありますが、こちらは一定時間後に処理を行うだけで繰り返しはしません。

----

setInterval(関数,時間の指定)という感じで使用します。
上のコードでは10ミリ秒(0.01秒)ごとに処理を繰り返していることになります。

----

次は中の処理ですが、
### 現在時間の取得
ここでは現在時間をnew Date();で取得しています。
console.log(new Date())などとすると現在の日付、時刻などが取得できているのがわかると思います。
それぞれ現在の時間、分、秒をget◯◯で取得しています。

----

### 時、分、秒を元に角度を計算
上で取得した現在の時間、分、秒を元に針の角度を割り出しています。

- 時間: 一周は360度なので現在の時間*(360/時間)としています。ですがそれだけだとダメなので現在の分*(360/時間(12)/分(60))を足しています。
- 分、秒数: ここそれぞれの現在の分数、秒数*(360 / 60)としています。

----

### 要素の取得
document.querySelectorで各クラスを指定し要素を取得しています。

----

### style追加
最後に取得した要素にstyleを追加し、現在時間を元に出した角度を設定します。
transform: rotate${}deg;

----

これを実行してみるとしっかり時計が動いていると思います。

こんな感じでcssとかjsを使えば割となんでも作れるなと思いました。
↓
ふざけた内容ですがこんな記事も書きました。
https://qiita.com/w-tdon/items/1023e159dafbc0fd960d
----

## 終わり