效果圖
下文是部分代碼,完整代碼參照:https://github.com/lemoncool/canvas-clock,可直接下載。首先看一下效果圖:每隔一秒會動態更新時間
一、前期准備
1. HTML中准備一個容器存放畫布,並為其設置width,height。
<div> <canvas id="clock" height="200px" width="200px"></canvas> </div>
2.在js中獲取canvas畫布元素,並獲得其上下文,對應的方法是 canvas.getContext
let dom = document.getElementById('clock'); //獲取畫布 let ctx = dom.getContext('2d'); //獲取canvas上下文 let width = ctx.canvas.width; //獲取預先設置的canvas畫布寬度 let height = ctx.canvas.height; //獲取預先設置的canvas畫布高度 let r = width / 2; //定義半徑,為后續繪制圓形圖案做准備
二、繪制圓盤背景
function drawBackground() { ctx.save(); //每次開始前都要保存當前畫布狀態,以免移動畫布影響后續繪制
ctx.translate(r, r); //將起始點位置移動至圓心
ctx.beginPath(); //每次開始繪制前必須開始一條路徑
ctx.lineWidth = 10 ; //設置繪制線的寬度
ctx.arc(0, 0, r - ctx.lineWidth / 2, 0, 2 * Math.PI, false); //畫一個整圓
ctx.stroke(); //對圓進行描邊
}
三、繪制小時刻度(1-12)及分鍾刻度(每個小時之間的小圓點 標記分鍾)
繪制前,首先看一下每個小時刻度(1,2,3,...12)在所在容器的坐標確定
所以,每一刻度點的 X = r*cos(角度)====>X = Math.cos(rad) * r Y = r*sin(角度)====>Y = Math.sin(rad) * r
但是 Math.cos(rad)與 Math.sin(rad) 中的角度都要求是弧度,弧度與角度的轉換見上圖,即圓周360度 = 弧度 2*Math.PI
所以,時鍾一圈共有12個小時,那個每小時所占的弧度為:rad = 2 * Math.PI / 12
時鍾一圈共有60的分鍾,那么每分鍾所占的弧度為:rad = 2 * Math.PI / 60
那么,清楚了小時和分鍾的弧度計算,我們開始繪制吧
var hourNumbers = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]; //定義標記小時的數組 hourNumbers.map(function (number, i) { //遍歷 取出各刻度及所在索引
//每個刻度所占弧度為索引乘以一小時的弧度,即 1點鍾30度,2點鍾60度,以此類推..
var rad = 2 * Math.PI / 12 * i;
var x = Math.cos(rad) * (r - 30 * rem);
var y = Math.sin(rad) * (r - 30 * rem); //確定各刻度點 X、Y坐標
ctx.textAlign = 'center'; //繪制的刻度在整個畫布左右居中
ctx.textBaseline = 'middle'; //同理,上下居中
ctx.font = 18 * rem + "px Arial"; //設置顯示刻度的數字 1,2,3.. 的字體及字號
ctx.fillText(number, x, y) //繪制文字
});
繪制標記分鍾的小圓點 道理 與繪制小時相似,只是弧度為60等分,繪制成實心的小圓點
繪制后的效果圖如下:
四、繪制時針、分針、秒針及圓心點
繪制時針與分針原理為 繪制直線
主要用到的方法為:ctx.rotate( ); ctx.moveTo(); ctx.lineTo(); ctx.lineCap= " ";
以下以繪制時針為例陳述原理:
function drawHour(hour, minute) { 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; //設置寬度 ctx.moveTo(0, 10); //移動起始點至(0,10) ctx.lineTo(0, -r / 2); //從起始點繪制到(0,r/2)點,負號表示方向向上 ctx.lineCap = 'round'; //設置結束線帽 ctx.stroke(); //描邊 ctx.restore(); //將畫布恢復到旋轉之前狀態 }
時針、分針、秒針、原點繪制后效果圖如下:
五、使時鍾指針動起來
原理為獲取當前時間 new Date(),設置定時器 setInterval(draw, 1000) 每隔一段時間更新繪制畫布
function draw() { ctx.clearRect(0, 0, width, height); //重新繪制之前清除畫布,否則狀態疊加,頁面顯示如下圖 var now = new Date(); //獲取當前時間 var hour = now.getHours(); //當前小時 var minute = now.getMinutes(); //當前分鍾 var second = now.getSeconds(); //當前秒數 drawBackground(); //繪制圓盤背景 drawHour(hour, minute); //繪制時針 drawMinute(minute); //繪制分針 drawSecond(second); //繪制秒針 drawDot(); //繪制原點 ctx.restore(); //回復畫布狀態 } setInterval(draw, 1000); //定時器執行整個繪畫方法
上圖為沒有清除畫布ctx.clearRect()的效果,所以切記 一定要在繪制之前清除畫布,重新畫。
六、時鍾出現了,且會自定更新
整個代碼邏輯參照了慕課網中 Silva Zhou 老師的講解,再次對老師表示感謝。
文章為自己記錄總結,方便日后使用。如果發現問題,歡迎留言指導~