好幾天沒有進行每日一練了,除了工作原因之外,還有因為近期看到同事發的各種剛入職場的學弟學妹們的簡歷,被上面寫的各種掌握的技能所刺激了。雖然可能不是那麼盡實,但著實的push自己一把,決定先把canvas啃下來。 我試水了畫了一個時鐘,和MDN的例子略有一點不同。I work it by myself ...
好幾天沒有進行每日一練了,除了工作原因之外,還有因為近期看到同事發的各種剛入職場的學弟學妹們的簡歷,被上面寫的各種掌握的技能所刺激了。雖然可能不是那麼盡實,但著實的push自己一把,決定先把canvas啃下來。
我試水了畫了一個時鐘,和MDN的例子略有一點不同。I work it by myself!
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body onload="draw()"> <canvas id="canvas" width="300" height="300"></canvas> <script> function init(){ var ctx = document.getElementById('canvas').getContext('2d'); ctx.save(); ctx.clearRect(0,0,300,300); ctx.translate(150,150); ctx.lineWidth = 4; ctx.strokeStyle = "#a77"; ctx.beginPath(); ctx.arc(0,0,100,0,Math.PI*2,true); ctx.stroke(); ctx.rotate(-Math.PI/2); //minute mark ctx.save(); for(var i = 0;i<60;i++){ if(i%5 != 0){ ctx.beginPath(); ctx.moveTo(90,0); ctx.lineTo(94,0); ctx.stroke(); } ctx.rotate(Math.PI/30); } ctx.restore(); //hour mark ctx.save(); for(var i=1;i<=12;i++){ ctx.beginPath(); ctx.moveTo(85,0); ctx.lineTo(95,0); ctx.stroke(); ctx.rotate(Math.PI/6); } ctx.restore(); window.requestAnimationFrame(clock); } function clock() { var ctx = document.getElementById('canvas').getContext('2d'); var now = new Date(); var sec = now.getSeconds(); var min = now.getMinutes(); var hr = now.getHours(); hr = hr>=12 ? hr-12 : hr; ctx.beginPath(); ctx.arc(0,0,82,0,Math.PI*2,false); ctx.clip(); ctx.clearRect(-90,-90,180,180); //write hour ctx.save(); ctx.lineWidth = 6; ctx.rotate(hr*Math.PI/6 + min*Math.PI/360 + sec*Math.PI/21600); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(50,0); ctx.stroke(); ctx.restore(); //write minute ctx.save(); ctx.lineWidth = 3; ctx.rotate(min*Math.PI/30 + sec*Math.PI/1800); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(65,0); ctx.stroke(); ctx.restore(); //write second ctx.save(); ctx.lineWidth = 1; ctx.rotate(sec*Math.PI/30); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(80,0); ctx.stroke(); ctx.restore(); window.requestAnimationFrame(clock); } init(); </script> </body> </html>View Code
這裡給出MDN的例子頁:點我點我
和MDN的例子不同的是,MDN每次都要重繪整個時鐘,而我的做法則將時鐘錶盤和3個指針分離開來,只需重繪指針。
我覺得這裡有兩個難點:一個是計算時分針的角度(分針走的同時,時針也會走一些角度)。一個是重繪指針的區域。
canvasRendingContext2D.rotate(angle)
這裡Math.PI是半圓,半圓有6個小時,所以Math.PI/6是一個小時時針所走的弧度。
因為分針轉完一圈,時針就走完1/12圈,所以計算時針對於minute所走的弧度可以這麼計算:Math.PI*2/60*12 =>Math.PI/360
秒針同理。
第二,重繪指針。
若不重繪指針,1分鐘之後,你將得到滿是360度秒針的時鐘。像這樣:
那麼如何才能重繪指針部分的區域呢?
我想到了裁剪。然後在裁剪的區域重繪。
這樣就OK了!(啦啦啦啦啦,手舞足蹈啦啦啦啦~~~)