在慕課上看到有老師講解canvas畫時鐘;本身也來研究一下;html
canvas clockcanvas
首先建立一個canvas瀏覽器
<canvas id='canvas' width="400" height="400"> 你的瀏覽器不支持canvas,請升級你的瀏覽器 </canvas>
設置畫布大小爲400*400,能夠在標籤中輸入不支持canvas的提示,提示瀏覽者;spa
而後開始操做canvas,先獲取canvas對象,而後獲取canvas的操做環境getContext
rest
var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d')
這裏知識前置一下,由於canvas繪畫只有一個進程(即上下文),要開始一個新的繪畫,必須把當前的繪畫結束了;因此 save 和 restore方法一般都成對出現;由於每次畫新的路徑時,都要把以前的繪畫給保存下來,結束後再把以前保存的狀態返回;code
每次新路徑須要調beginpath方法;htm
代碼中出現每次須要畫新的路徑時,能夠用save保存,畫好了,再restore;這樣的作法可讓canvas保持每次繪畫都是以初始化爲標準去繪畫;對象
由於是畫時鐘,爲了方便定位,先把canvas的原點設置爲畫布的中心;blog
ctx.translate(canvasW/2,canvasW/2);
在設置好原點後,能夠進行背景的描繪,在寫的過程當中,能夠查閱canvas參考手冊進程
傳送門:canvas參考手冊
//繪製背景 ctx.save(); ctx.rotate(Math.PI/2); //背景顏色塊 ctx.fillStyle = '#f2f2f0'; ctx.fillRect(-200,-200,110,400); ctx.beginPath(); ctx.fillStyle = '#b0b2b9'; ctx.fillRect(-90,-200,180,400); ctx.beginPath(); ctx.fillStyle = '#f2f2f0'; ctx.fillRect(90,-200,110,400); //時鐘外框 ctx.beginPath(); ctx.arc(0,0,R,0,2*Math.PI); ctx.lineWidth = 7; //設置線條寬 ctx.strokeStyle = '#9b9ca3'; ctx.stroke(); //時鐘背景 ctx.beginPath(); var myGradient = ctx.createRadialGradient(0, 0, 0, 0,0,75); myGradient.addColorStop(0, "#fff"); myGradient.addColorStop(1, "#eceef0"); ctx.fillStyle = myGradient; ctx.arc(0,0,R,0,2*Math.PI); ctx.fill(); ctx.restore();
因爲canvas畫圓是以X軸的正方向爲起始點,即三點鐘方向,因此爲了方便畫圖,能夠把canvas一開始就旋轉90度,旋轉到12點方向;
//將座標軸逆時針旋轉90度,x軸正方向對準12點方向 ctx.rotate(-Math.PI/2);
在畫背景的時候方即可以把canvas還原以便畫圖
ctx.rotate(Math.PI/2);
描繪好背景以後能夠描繪大時鐘的刻度,大刻度每90度就是一個大的時刻,這個時鐘有大小兩個刻度,其實同理;
//刻度
for (var i = 0; i < 60; i++) { ctx.save(); ctx.beginPath(); //設置線條的寬度 ctx.lineWidth = 1; //設置線條的顏色 ctx.strokeStyle = "#999"; ctx.moveTo(countX(clockR,i), countY(clockR,i)); if (i % 15 != 0){ ctx.lineTo(countX(clockR + 5,i), countY(clockR+5,i)); } else { ctx.lineTo(countX(clockR + 17,i), countY(clockR+17,i)); } ctx.stroke(); ctx.restore(); }
這裏countX和countY兩個函用來求每一個刻度的起始點,即X座標和Y座標;
//計算X軸座標 function countX(radii, angle, percent){ if (!radii || (typeof angle == 'undefined')){ return; } var _width = radii * Math.cos(Math.PI / (percent || 30) * angle); return _width; } //計算Y軸座標 function countY(radii, angle, percent){ if (!radii || (typeof angle == 'undefined')){ return; } var _height = radii * Math.sin(Math.PI / (percent || 30) * angle); return _height; }
祭個圖好明白一些
B點的y座標爲 y = 半徑 * Math.sin(角度);(鄰邊對斜邊)
B點的x座標爲 x = 半徑 * Math.cos(角度);(對邊對斜邊)
畫好刻度,就能夠畫分針,秒針和時針了,其實都是同一個原理,在這裏講解一下分針;
//分針 ctx.save(); ctx.beginPath(); ctx.lineWidth = 3; ctx.strokeStyle = '#0a1227'; //"round" 和 "square" 會使線條略微變長。 //設置canvas末端樣式 ctx.lineCap = 'round'; ctx.moveTo(countX(MinR,opt.min + opt.sec/60), countY(MinR,opt.min + opt.sec/60)); ctx.lineTo(countX(MinR + 55,opt.min + opt.sec/60), countY(MinR + 55,opt.min + opt.sec/60)); ctx.stroke(); ctx.restore();
分針這裏會跟着秒針的滾動而滾動,所加上了sec/60,秒針值向的百分比;