フロントエンドエンジニアになりたい

デザイナーなのかコーダーなのかディレクターなのかよくわからない人のブログ。趣味で絵を描きました(過去形)

Canvasでシンプルなアナログ時計

codepen.io

シンプルな時計の実装です。

三角関数で現在の時間の位置を求めて描画を繰り返します。 フレームレート的には1fpsで十分なのでrequestAnimationFrameを使わなくても良かったかもしれません。

針の描画

三角関数で現在の時間のそれぞれの針の位置を求めて線を引いています。

drawHands()の中でまずそれぞれの時間の角度を求めています。

function drawHands() {
  var date = new Date();
  // 現在の時間を取得
  var h = date.getHours();
  h = h > 12 ? h - 12 : h;
  var m = date.getMinutes();
  var s = date.getSeconds();
  // それぞれの針の角度を求めて drawHand へ渡す
  drawHand(Math.PI/6*h + Math.PI/(60*6)*m + Math.PI/(60*60*6)*s - Math.PI/2, true);
  drawHand(Math.PI/30*m + Math.PI/(60*30)*s - Math.PI/2, false);
  drawHand(Math.PI/30*s - Math.PI/2, false);
}

半周 / 半周分の時間の距離 * 現在の時間でその時間の角度を求めることができます。 1週分から求めても一緒ですが、Math.PI(π)は半周なのでこの方が式が少なく済みます。

さらに時針の場合は経過分と秒の分の角度を、分針の場合は経過秒の角度を、それぞれ加算しています。

角度はx軸を0時したものになっているので、1/4の角度を減算してy軸が0時となるようにします。

drawHand()では、それぞれの針の角度から座標を計算してそこまでの線を引いています。

function drawHand(angle, isHour) {
  var handRadius = isHour ? RADIUS - HAND_TRUNCATION - HOUR_HAND_TRUNCATION
                          : RADIUS - HAND_TRUNCATION;
  ctx.moveTo(canvas.width/2, canvas.height/2);
  // cosθ, sinθ に針の長さをかけたものがx, yの座標になります
  ctx.lineTo(canvas.width/2 + Math.cos(angle) * handRadius,
              canvas.height/2 + Math.sin(angle) * handRadius);
  ctx.stroke();
}

※コードはオライリープログラミングHTML5 Canvasのサンプルを修正して使用しています。

参考