今回はjavascriptでアナログ時計を作ってみました。
なぜ作ったか
アナログ時計なので
時間周りの処理が必要なのでそこらへんの勉強になるのと、
あまりwebサイトではアナログ時計を見ないですが、サイトにあったら意外とお洒落かもと思って
作ってみました。
作るアナログ時計の完成イメージ
基本的な丸型の時計です。
コード
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
.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
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;
これを実行してみるとしっかり時計が動いていると思います。