使用<canvas>元素不是很是難,但須要一些基本的HTML和JavaScript知識。canvas
今天咱們來利用canvas API繪製一個時鐘,先上圖:函數
畫圖以前,先把思路捋一遍:首先分解一下這個時鐘的圖形,它是由錶盤(圓形)和指針(直線)組成。spa
canvas中圓形與矩形差距很大,canvas並無提供專門繪製圓形的方法,但能夠繪製圓弧,將圓弧首尾相連獲得圓形3d
arc( x , y , radius , 起始弧度 , 結束弧度 , 旋轉方向)
x,y --- 圓心座標
radius --- 半徑
弧度和角度的關係 --- 弧度 = 角度*Math.PI/180
例:2π是360°(完整的圓形)
旋轉方向 --- true:逆時針;false:順時針(默認)指針
掌握畫圓大法後,就能夠着手施工了:code
首先準備好畫布對象
<canvas id="myClock" width="500" height="500"></canvas>
接着獲取上下文對象blog
var canvas = document.getElementById('myClock'); var con = canvas.getContext('2d');
分解功能:ip
1.錶盤上的刻度(60個表示秒的刻度,12個表示小時的刻度)get
1.1 60個秒刻度-->360°/60-->6°一個小格
//定義原點和半徑 var x = 250; var y = 250; var r = 150; con.moveTo(x,y); con.arc(x,y,r,0,6*Math.PI/180); con.moveTo(x,y); con.arc(x,y,r,6*Math.PI/180,12*Math.PI/180); con.stroke(); ……
先來作個小實驗,以上代碼片斷將會獲得這個圖形
利用循環,將以上代碼完善
//定義原點和半徑 var x = 250; var y = 250; var r = 150; //繪製秒刻度開始 con.beginPath();//爲了避免影響其餘繪圖,加上起始路徑 for (var i = 0; i < 60; i++) { con.moveTo(x, y); //以圓心爲起點 con.arc(x, y, r, 6 * i * Math.PI / 180, 6 * (i + 1) * Math.PI / 180);//繪製一段6°的圓弧 } con.closePath(); //爲了避免影響其餘繪圖,加上起始路徑 con.stroke();
此刻,獲得以下圖形
怎麼看怎麼不像錶盤咧?!爲了達到秒刻度的效果,只需在上面覆蓋一個較小的白色實心圓形便可
//較小的白色圓盤 con.beginPath(); con.moveTo(x,y); con.arc(x,y,0.95*r,0,2*Math.PI); con.closePath(); con.fillStyle = '#fff';//填充圖形背景色 con.fill(); //實心圓
如今看上去,錶盤的雛形算是出來了。
一樣的步驟,將小時刻度也畫出來,爲了區分小時刻度和秒刻度,能夠加粗小時刻度的線條
1.2 12個小時刻度-->360°/12-->30°一個大格
con.beginPath();//爲了避免影響其餘繪圖,加上起始路徑 con.lineWidth = 4; //加粗小時刻度 for(var i = 0;i<12;i++){ con.moveTo(x,y); con.arc(x,y,r,30*i*Math.PI/180,30*(i+1)*Math.PI/180); } con.closePath(); //爲了避免影響其餘繪圖,加上起始路徑 con.stroke();
最後,再疊加一個較小的白色實心圓心,錶盤就畫完了(最難的部分也搞定了)
con.fillStyle = '#fff'; con.beginPath(); con.moveTo(x, y); con.arc(x, y, 0.85 * r, 0, 2 * Math.PI); con.closePath(); con.fill();
總得來講,畫表盤就和化妝同樣,須要層層疊加
2.時、分、秒針
//注意:考慮到針要以圓心爲中心旋轉 con.lineWidth = 5; //定義時針線條的寬度 con.beginPath(); con.moveTo(x,y); //仍是以圓心爲起點 con.arc(x,y,0.5*r,0,0);//此處半徑即時針的長度 con.closePath(); con.stroke();
分針和秒針就不作贅述,修改lineWidth的值和圓弧的半徑便可
3.讓時鐘走起來
如何讓秒針隔一秒動一下呢?是否是很快想到這個方法--->setInterval()
…… //獲取當前系統時間 var today = new Date(); var hh = today.getHours(); var mm = today.getMinutes(); var ss = today.getSeconds(); //時針對應的弧度 var hhVal = (-90 + hh * 30 + mm / 2)*Math.PI/180; //-90:canvas畫圓的起始點在錶盤的3個字,而時鐘的起始點應在12個字。+mm/2:時針不會一直只在整點的位置,分針走30分鐘,時針多走15° var mmVal = (-90 + mm * 6) * Math.PI / 180; var ssVal = (-90 + ss * 6) * Math.PI / 180; …… con.arc(x, y, 0.5 * r, hhVal, hhVal); …… //調用函數 setInterval(toDraw, 1000);
組合好代碼後,時鐘就能走起來了:(^-^)V
奉上完整代碼:
HTML部分
<canvas id="myClock" width="500" height="500"></canvas> <p id="showDate"></p>
JavaScript部分
window.onload = function () { //獲取上下文對象 var canvas = document.getElementById('myClock'); var con = canvas.getContext('2d'); //自定義函數---畫表盤,針 function toDraw() { //定義原點和半徑 var x = 250; var y = 250; var r = 150; //繪製秒刻度開始 con.beginPath(); for (var i = 0; i < 60; i++) { con.moveTo(x, y);//以圓心爲起點 con.arc(x, y, r, 6 * i * Math.PI / 180, 6 * (i + 1) * Math.PI / 180);//繪製一段6°的圓弧 } con.closePath(); //爲了避免影響其餘繪圖,加上起始路徑 con.stroke(); //較小的白色圓盤 con.fillStyle = '#fff'; con.beginPath(); con.moveTo(x, y); con.arc(x, y, 0.95 * r, 0, 2 * Math.PI); con.closePath(); con.fill(); //實心圓 //繪製秒刻度結束 //同理繪製小時刻度 con.beginPath(); con.lineWidth = 4; //加粗小時刻度 for (var i = 0; i < 12; i++) { con.moveTo(x, y); con.arc(x, y, r, 30 * i * Math.PI / 180, 30 * (i + 1) * Math.PI / 180); } con.closePath(); //爲了避免影響其餘繪圖,加上起始路徑 con.stroke(); //較小的白色圓盤 con.fillStyle = '#fff'; con.beginPath(); con.moveTo(x, y); con.arc(x, y, 0.85 * r, 0, 2 * Math.PI); con.closePath(); con.fill(); //繪製小時刻度結束 //獲取當前系統時間 var today = new Date(); var hh = today.getHours(); var mm = today.getMinutes(); var ss = today.getSeconds(); document.getElementById('showDate').innerHTML = hh+':'+mm+':'+ss; //時針對應的弧度 var hhVal = (-90 + hh * 30 + mm / 2) * Math.PI / 180; var mmVal = (-90 + mm * 6) * Math.PI / 180; var ssVal = (-90 + ss * 6) * Math.PI / 180; //開始繪製時、分、秒針(注意:考慮到針要以原點爲中心旋轉) con.lineWidth = 5; //時針 con.beginPath(); con.moveTo(x, y); con.arc(x, y, 0.5 * r, hhVal, hhVal); con.closePath(); con.stroke(); con.lineWidth = 3; //分針 con.beginPath(); con.moveTo(x, y); con.arc(x, y, 0.65 * r, mmVal, mmVal); con.closePath(); con.stroke(); con.lineWidth = 1; //秒針 con.beginPath(); con.moveTo(x, y); con.arc(x, y, 0.8 * r, ssVal, ssVal); con.closePath(); con.stroke(); } //每隔1秒調用一次函數 setInterval(toDraw, 1000); }