Canvas時計を描く
10949 ワード
前言
何を勉強しても、手を出さないと、永遠にマスターできない.canvas APIを勉強すると、直線や円などの画法で描くだけで、canvasは簡単すぎると思います.しかし、本当に絵を描くと、多くの問題に直面します.
次に紹介するのはcanvas時計で、主にみんなと私の学習過程を分かち合います.
canvasの学友を知らないで、先に学びます:Canvasキャンバス
関連ジオメトリ
時計は1つの円で、主に1時間あたりの数字と目盛りを含んで、それらの位置座標はどのように計算しますか?
上の図から容易に得られる:−x=r*cos(角度)−y=r*sin(角度)
Math
対象内のsin()
とcos()
の方法は弧を使用しているので、変換が必要ですしかし、今回の使用では実際には使われていない.時計の目盛りなどは等比例で区切られているため、2 PIを目盛り数などで割るだけで相応の弧度が得られる.
時計回り、分針、秒針は、いずれも直線が一定の角度を回転させることで得られる
けいじょうかんすう
canvasキャンバスを使用するには、まず図面コンテキスト環境を取得する必要があります.
var canvas = document.getElementById('clock');
var cxt = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
var r = width / 2;
canvas要素の幅の高さを取得し、半径rを最大の半径、すなわち幅の半分として定義します.
function drawBg() {
//
cxt.save();
cxt.translate(r,r);
//
cxt.beginPath();
cxt.arc(0, 0, r - 5, 0, 2*Math.PI, true);
cxt.lineWidth = 8;
cxt.stroke();
//
var hour = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
hour.forEach(function(num,i){
var rad = 2 * Math.PI / 12 * i;
var x = Math.cos(rad) * (r - 30);
var y = Math.sin(rad) * (r - 30);
cxt.font = "18px sans-serif"
cxt.textAlign = "center";
cxt.textBaseline = "middle";
cxt.fillText(num, x, y);
});
//
for (var i = 0; i < 60; i++) {
var rad = 2 * Math.PI / 60 * i;
var x = Math.cos(rad) * (r - 18);
var y = Math.sin(rad) * (r - 18);
cxt.beginPath();
if(i%5 == 0){
cxt.fillStyle = "#000";
cxt.arc(x, y, 2, 0, 2*Math.PI, true);
}
else {
cxt.fillStyle = "#bbb";
cxt.arc(x, y, 2, 0, 2*Math.PI, true);
}
cxt.fill();
}
}
ポイント:-
cxt.save()
ここには元の原点位置が保存されています.canvasをクリアするときにcxt.clearRect()
メソッドを簡単に呼び出すためです.cxt.translate(r,r)
は、原点を(r,r)位置に置く.すべての目盛り数などが同心円を中心に行われるため、原点を円心上に置くのは、位置座標の計算を容易にするためである.なお、この方法では、後の図面がこの原点に基づいてsin()
とcos()
の正負値がx
、y
の正負値に対応しないようにするためです.cxt.textAlign = "center"
とcxt.textBaseline = "middle"
は、テキストの位置合わせ方法であり、設定しないと時間数のオフセット時計の針を引く
//
function drawHour(hour, minute) {
cxt.save();
var rad = 2 * Math.PI / 12 * hour + 2 * Math.PI / 12 * minute / 60;
cxt.beginPath();
cxt.rotate(rad);
cxt.moveTo(0, 15);
cxt.lineTo(0, -r/2);
cxt.lineWidth = 5;
cxt.lineCap = "round";
cxt.stroke();
cxt.restore();
}
ポイント:-回転するたびに後の描画に影響するため、ここで描画環境を保存し、描画時計回りの終了後に元の描画環境にリセットします.
画分針、秒針、中心点関数
//
function drawMinute(minute) {
cxt.save();
var rad = 2 * Math.PI / 60 * minute;
cxt.beginPath();
cxt.rotate(rad);
cxt.moveTo(0, 18);
cxt.lineTo(0, -r + 40);
cxt.lineWidth = 3;
cxt.lineCap = "round";
cxt.stroke();
cxt.restore();
}
//
function drawSecond(second) {
cxt.save();
var rad = 2 * Math.PI / 60 * second;
cxt.beginPath();
cxt.rotate(rad);
cxt.moveTo(0, 25);
cxt.lineTo(2, 25);
cxt.lineTo(-2, 25);
cxt.lineTo(-1, -r + 25);
cxt.lineTo(1, -r + 25);
cxt.lineTo(2, 25);
cxt.lineWidth = 1;
cxt.fillStyle = "#f00";
cxt.fill();
cxt.restore();
}
//
function drawDot() {
cxt.beginPath();
cxt.arc(0, 0, 4, 0, 2*Math.PI,true);
cxt.fillStyle = "#fff";
cxt.fill();
}
:-図面環境を上の時計回りに保存します.リアルタイムの描画
//
function draw() {
cxt.clearRect(0, 0, width, height);
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
drawBg();
drawHour(hour,minute);
drawMinute(minute);
drawSecond(second);
drawDot();
cxt.restore();
}
draw();
setInterval(function(){
draw();
},1000);
ポイント:-
cxt.restore()
ここでリセットされているのは時計を描くときに保存されている描画環境です.原点をデフォルトにリセットしてから、矩形領域をクリアする方法を使用します.cxt.clearRect(0, 0, width, height)
canvas領域をクリアし、再描画します.毎回描かれている時計回りや分針などは、残されているので、setInterval()
メソッドを呼び出す前に、ペイントを呼び出す必要があります.そうしないと、1秒遅れた表示最適化
現在の時計回りは
200px
の正方形に基づいて描かれています.では、幅を大きくすると、どうなるのでしょうか.600px: 時計の針は醜くなり、大きさは比例しない、つまり歪みです.
では、どうすれば歪まないことができますか?
クロックは正方形の領域であり、円の体現であるため、すべての関連する大きさは半径または幅に比例するだけで実現することができる.
まず、それらのスケール関係を計算します.
200 / width = 13 / length
すなわち、
200px
の幅において13px
の大きさとして表現される場合、width
の幅においてlength
の大きさとして表現されるべきである.すなわち、
length = 13 * width/200
得られる比例関係は、width/200
である.スケールを定義します.
var rem = width / 200;
後の各関数において,関連する大きさにこの比例関係を乗じるだけで実現でき,どんなに幅の広いクロックでも完璧に表現できる.