山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

[JavaScript] 時計の描画

時計

JavaScriptcanvas を使ってアナログ時計を描画します。

コードについて

目盛り

時計の目盛りは Path 設定して線を描いています。

  drawDial(ctx, cx, cy) {
    // 時針の目盛りを描画
    ctx.strokeStyle = "rgb(0, 0, 255)";
    for (let i = 0; i < 12; i++) {
      ctx.beginPath();
      let t = Math.PI * 30 * i / 180;
      ctx.moveTo(cx + 150 * Math.cos(t), cy + 150 * Math.sin(t));
      ctx.lineTo(cx + 130 * Math.cos(t), cy + 130 * Math.sin(t));
      ctx.stroke();
    }
    // 分針の目盛りを描画
    ctx.strokeStyle = "rgb(0, 255, 0)";
    for (let i = 0; i < 60; i++) {
      if ((6 * i) % 30 == 0) continue;
      ctx.beginPath();
      let t = Math.PI * 6 * i / 180;
      ctx.moveTo(cx + 150 * Math.cos(t), cy + 150 * Math.sin(t));
      ctx.lineTo(cx + 140 * Math.cos(t), cy + 140 * Math.sin(t));
      ctx.stroke();
    }
  }

時計の針の移動

時計の針の移動はアニメーション的な動きをするので、requestAnimationFrame() を使います。あまり、使い方を分かっていないんですが、初めに、描画の部分を呼び出します。

requestAnimationFrame(() => clock.drawClock(0))

そして、

  drawClock(t) {
    this.ctx.clearRect(0, 0, 300, 300);
    this.drawDial(this.ctx, this.cx, this.cy);
    this.drawHandOfWatch(this.ctx, t, this.cx, this.cy);
    window.requestAnimationFrame(() => this.drawClock((t + 1)) % 43200);
  }

のように再帰的に呼び出します。

時間について

描画されるたびに、1秒経過するという処理にしています。時計は、0秒から12時間まで表現できるので、 t 秒における、 s秒、 m分、 h 時 は、

 s = t \bmod 60

 m = \dfrac{t}{60} \bmod 60

 h = \dfrac{t}{3600} \bmod 12

となります。次に、秒針、分針、時針の角度  \theta_1, \theta_2, \theta_3は、

 \theta_1 = 6s

 \theta_2 =6(m + \dfrac{s}{60})

 \theta_3 = 30(h + \dfrac{m}{60} + \dfrac{s}{3600})

となります。秒針は1秒で6度、分針は1分で6度、時針は1時間で30度動きます。

内容的には4章です。