まず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.






