まずHTML側は
<body onload="init()"> <canvas id="aaa" width="250" height="250" style="background-color:#ffffcc;"></canvas> <p id="now"></p> <p id="debug"></p> </body>
とした。ページ読込時にinit関数を呼び出して、そこでキャンバスの設定を行う予定。キャンバスのサイズは250×250の黄色。
init関数は以下のように。
<script> var ctx; var intervalID = NaN; function init() { var canvas = document.getElementById("aaa"); ctx = canvas.getContext("2d"); ctx.translate(125,125); //0,0を125,125へ移動 clearInterval(intervalID); intervalID = setInterval(moveClock, 1000); }
グローバル変数でctxと、intervalID を宣言。
translate(125,125)関数によって、座標軸を右へ125下へ125行った場所を0,0に変更しますした。ここに時計の円を描く予定です。
setInterval関数を使って1000ミリ秒(1秒)ごとに、描画をするようにしました。moveClock関数で描画を実行します。
moveClock関数は以下のようにしました。
function moveClock() { ctx.clearRect(-125, -125, 250, 250);//描画をいったん全部消す //時計板の円を描く ctx.strokeStyle = "#aaaaaa"; ctx.fillStyle = "#00ffff"; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(0, 0, 100, 0, 2*Math.PI); //125,125を中心とする半径100の円 ctx.closePath(); ctx.stroke(); //現在時刻を取得 var now = new Date(); h = now.getHours() % 12; //24時間表記から12時間表記へ m = now.getMinutes(); s = now.getSeconds(); document.getElementById("now").textContent = h + "時" + m + "分" + s + "秒"; //短針は12時間で1回転、角度は360÷12= 30度ずつ回転する //長針は1時間で1回転、角度は360÷60= 6度ずつ回転する //秒針は1分で1回転、 〃 var tansinAngle = 30/180*Math.PI * h; //短針の角度 var chosinAngle = 6/180*Math.PI * m; //長針の角度 var byosinAngle = 6/180*Math.PI * s; //秒針の角度 document.getElementById("debug").textContent = "短針角度:" + 30*h + " 長針角度:" + 6*m + " 秒針角度: " + 6*s; ctx.save(); //状態を保持 ctx.rotate(byosinAngle); //秒針ぶんだけ回転させて //秒針の描画 ctx.strokeStyle = "#666666"; //線の色 ctx.lineWidth = 1; //線の幅 ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(0, -90); ctx.stroke(); ctx.restore(); //状態をsaveのポイントに戻す ctx.save(); //状態を保持 ctx.rotate(chosinAngle); //長針ぶんだけ回転させて //長針の描画 ctx.strokeStyle = "#6666ff"; //線の色 ctx.lineWidth = 3; //線の幅 ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(0, -80); ctx.stroke(); ctx.restore(); //状態をsaveのポイントに戻す ctx.save(); //状態を保持 ctx.rotate(tansinAngle); //秒針ぶんだけ回転させて //秒針の描画 ctx.strokeStyle = "#ff6666"; //線の色 ctx.lineWidth = 5; //線の幅 ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(0, 50); ctx.stroke(); ctx.restore(); //状態をsaveのポイントに戻す }
時計の描画はこのようにしました。まず前回描画したものを消さないといけないので、ctx.clearRect(-125, -125, 250, 250)を行っています。これは座標(-125,-125)から幅250高さ250をクリアしています。
時計板の円を描くのは前回やったような感じ。
現在時刻を取得して、HTMLのpタグのnowに表示。
時計の「短針」「長針」「秒針」の角度をラジアンで求めています。
短針は1~12時で1週360度だから1時間あたり30度ずつ動くので30/180*Math.PI * h;で計算。
長針は1週360度だけど1分単位に6度ずつ動くので6/180*Math.PI * m;で計算。
同様に秒針は6/180*Math.PI * s;で計算。
まずまず秒針の描画。
ctx.save()関数で状態を保持しています。
rotate関数を使って座標をbyosinAngleだけ回転してからmoveToで円の中心(0,0)から、lineToで(0,-90)まで直線を描画。
描画が終われば、ctx.restore()で、saveした時点の座標に戻す。
これを、短針と長針も同じように描画。この関数が1000ミリ秒ごとに読み込まれるので、時計が動いているように針がまわってくれるようになりました。
CodePenの記述は以下のとおり。
See the Pen
canvas-myclock by pghappy (@pghappy)
on CodePen.