ほんっとにはじめてのHTML5とCSS3
<canvas>サンプル13-2

Canvasでアニメーションを作る

●requestAnimationFrame() で短針、長針もあるアナログ時計

*使い方の詳細は、
「ほんっとにはじめてのHTML5:[69-14] canvasのアニメーションの基本を見てみよう」

サンプル3_requestAnimationFrame() でアナログ時計を作ってみた

window.requestAnimationFrame() メソッドを使っています。
これは、アニメーションのために再描画させたい指定を呼び出すんだそうです。およそ毎秒60回の再描画をするらしい。
引数は1個だけで、描画させたい指定を書きます。

また、new Date() で時刻をゲットして、getSeconds() で秒、getMinutes() で分、getHours() で時を数値でゲットしています。その値を使ってそれぞれの時計の針を回転させています。
(秒針は先っぽのマルだけにしたけど)

この時計のアニメーションは、MDN(Mozilla Developer Network)Basic animations を参考にさせていただきました。
(ほぼコピペ。このページに合うようにソースを編集した後、時計のサイズやデザインを変えました。お世話になります。)

onload = function() {
  window.requestAnimationFrame(clock);
};

function clock(){
  var now = new Date();
  var ctx = document.getElementById('canvas1').getContext('2d');
  ctx.save();
  ctx.clearRect(0,0,300,300); //毎回canvas全体をクリアしてから描画する
  ctx.translate(150,150);     //回転の起点をcanvasの中心にする
  ctx.rotate(-Math.PI/2);     //-90度回転で0時を起点に(デフォの起点は3時のところ)
  ctx.strokeStyle = '#999';
  ctx.fillStyle = '#000';
  ctx.lineWidth = 3;
  ctx.lineCap = 'round';
  
  // 時計のフレームの描画
  ctx.save();
  ctx.beginPath();
  ctx.arc(0,0,142,0,Math.PI*2,true);
  ctx.stroke();
  ctx.fill();
  ctx.restore();

  // 文字盤の「時間」マークを12個
  ctx.save();
  for (var i=0;i<12;i++){
    ctx.beginPath();
    ctx.rotate(Math.PI/6);
    ctx.lineWidth = 9;
    ctx.moveTo(123,0);
    ctx.lineTo(124,0);
    ctx.stroke();
  }
  ctx.restore();

  // 文字盤の「分」マークを60個
  ctx.save();
  for (i=0;i<60;i++){
    /*if (i%5!=0) {*/
    ctx.beginPath();
    ctx.rotate(Math.PI/30);
    ctx.lineWidth = 5;
    ctx.moveTo(123,0);
    ctx.lineTo(124,0);
    ctx.stroke();
    /*}*/
  }
  ctx.restore();
 
  var sec = now.getSeconds();
  var min = now.getMinutes();
  var hr  = now.getHours();
  hr = hr>=12 ? hr-12 : hr; //三項演算子(hrが12か12より大きけりゃ12引く。じゃなきゃそのまま)
 
  // 長針の描画
  ctx.save();
  // 1時間に30度、1分には0.5度、1秒には「180/6時間分の秒数」度、じわ〜っと動くように
  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
  ctx.lineWidth = 10;
  ctx.beginPath();
  ctx.moveTo(0,0);
  ctx.lineTo(80,0);
  ctx.stroke();
  ctx.restore();

  // 短針の描画
  ctx.save();
  // 1分に6度、1秒には「180/30分の秒数」度、動くように
  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
  ctx.lineWidth = 6;
  ctx.beginPath();
  ctx.moveTo(0,0);
  ctx.lineTo(105,0);
  ctx.stroke();
  ctx.restore();
 
  // 秒針の描画
  ctx.save();
  // 1秒に6度ずつ動くように
  ctx.rotate(sec * Math.PI/30);
  ctx.strokeStyle = '#0c0';
  ctx.fillStyle = '#fff';
  // 円の白塗り
  ctx.beginPath();
  ctx.arc(123,0,7,0,Math.PI*2,true);
  ctx.fill();
  // 外側の円
  ctx.beginPath();
  ctx.lineWidth = 2;
  ctx.arc(123,0,7,0,Math.PI*2,true);
  ctx.stroke();
  // 内側の点
  ctx.beginPath();
  ctx.lineWidth = 5;
  ctx.moveTo(123,0);
  ctx.lineTo(124,0);
  ctx.stroke();
  ctx.restore();
  ctx.restore();

  window.requestAnimationFrame(clock);
}