這次我通過用Canvas實現(xiàn)一個時鐘來牵现,學習Canvas繪圖的基本API和用法,對于例子里面用到的每一個API科乎,我都會詳細的列出它的用法贼急。
首先來看一下繪制完成后的效果圖
時鐘.PNG
這個時鐘可以通過調(diào)整畫布的寬高來增大和縮小空闲,效果不會有改變走敌。
繪制的基本思路是
- 時鐘背景圖的繪制
- 時針、分針、秒針、原點的繪制
- 讓時針矫户、分針残邀、秒針動起來
時鐘背景圖的繪制
首先在HTML中定義一個寬高為400的畫布Canvas
<div>
<canvas id="clock" height="400" width="400"></canvas>
</div>
然后獲取畫布元素,定義畫布的執(zhí)行上下文ctx
/*獲取畫布元素*/
var dom = document.getElementById("clock");
/*獲得2d執(zhí)行環(huán)境*/
var ctx = dom.getContext('2d');
獲取畫布的寬高,以及定義時鐘的半徑
/*定義半徑為寬度的一半*/
var r = width/2;
/*縮放比例*/
var rem = width / 200;
接下來進行背景圖的繪制驱闷,包括背景圓空另,12個數(shù)字扼菠,還有60個點的繪制坝咐,代碼如下,注釋已經(jīng)詳細說明了過程
/*畫時鐘的背景圖*/
function drawBackground(){
/*一開始先把畫布的初始狀態(tài)保存下來*/
ctx.save();
/*將畫布的中心原點由(0,0)變成(r,r)*/
ctx.translate(r,r);
/*開始繪畫*/
ctx.beginPath();
/*定義畫筆的寬度*/
ctx.lineWidth = 10*rem;
/*繪制一個圓*/
ctx.arc(0,0,r-5*rem,0,2*Math.PI,false);
/*進行填充*/
ctx.stroke();
/*畫時鐘上的12個數(shù)字*/
var hourNumber = [3,4,5,6,7,8,9,10,11,12,1,2];//12個小時數(shù)
ctx.font = 18*rem +'px Arial';//定義字體大小和樣式
ctx.textAlign='center';//將文本內(nèi)容居中對齊
ctx.textBaseline='middle';//將文本基線設置為中線
hourNumber.forEach(function(number,i){
var rad = 2*Math.PI/12*i;//每個數(shù)字的弧度
/*求出數(shù)字存放位置的x和y坐標*/
var x = Math.cos(rad)*(r - 30*rem);
var y = Math.sin(rad)*(r - 30*rem);
/*填充數(shù)字*/
ctx.fillText(number,x,y);
});
/*繪制60個點*/
for(var i=0;i<60;i++){
var rad = 2*Math.PI/60*i;
var x = Math.cos(rad)*(r-18*rem);
var y = Math.sin(rad)*(r-18*rem);
ctx.beginPath();
/*如果是小時數(shù)的位置就繪制成黑色*/
if(i % 5 === 0){
ctx.fillStyle = "#000";
ctx.arc(x,y,2*rem,0,2 * Math.PI,false);
}else{
ctx.fillStyle = "#ccc";
ctx.arc(x,y,2*rem,0,2 * Math.PI,false);
}
ctx.fill();
}
}
時針秧饮、分針盗尸、秒針咪辱、圓點的繪制
代碼如下
function drawHour(hour,minute){
/*再次保存當前畫布的狀態(tài)*/
ctx.save();
ctx.beginPath();
var rad = 2 * Math.PI / 12 * hour;
var mrad = 2 * Math.PI / 12 /60 * minute;
ctx.rotate(rad+mrad);//旋轉當前繪畫
ctx.lineWidth = 6*rem;
ctx.lineCap = 'round';
ctx.moveTo(0,10*rem);
ctx.lineTo(0,-r/2);
ctx.stroke();
/*返回最近的一次SAVE的畫布狀態(tài)*/
ctx.restore();
}
function drawMinute(minute){
ctx.save();
ctx.beginPath();
var rad = 2 * Math.PI / 60 * minute;
ctx.rotate(rad);
ctx.lineWidth = 3*rem;
ctx.lineCap = 'round';
ctx.moveTo(0,10*rem);
ctx.lineTo(0,-r + 40*rem);
ctx.stroke();
ctx.restore();
}
function drawSecond(second){
ctx.save();
ctx.beginPath();
ctx.fillStyle = "#c14543";
var rad = 2 * Math.PI / 60 * second;
ctx.rotate(rad);
ctx.moveTo(-3,20*rem);
ctx.lineTo(3,20*rem);
ctx.lineTo(1,-r+18*rem);
ctx.lineTo(-1,-r+18*rem);
ctx.fill();
ctx.restore();
}
function drawDot(){
ctx.beginPath();
ctx.fillStyle="#fff";
ctx.arc(0,0,3*rem,0,2*Math.PI,false);
ctx.fill();
}
讓時鐘動起來
function draw(){
/*動態(tài)改變的時候历恐,每一次都要先將之前的矩形畫布清除掉弱贼,然后重新繪制*/
ctx.clearRect(0,0,width,height);
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
drawBackground(width);//背景
drawHour(hour,minute);//小時
drawMinute(minute);//分鐘
drawSecond(second);//秒
drawDot();//中心原點
/*恢復到一開始save的那個畫布狀態(tài)吮旅,進行重新繪制*/
ctx.restore();
}
draw();
setInterval(draw,1000);