應用canvas繪制動態時鍾--每秒自動動態更新時間


效果圖

下文是部分代碼,完整代碼參照: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 老師的講解,再次對老師表示感謝。

文章為自己記錄總結,方便日后使用。如果發現問題,歡迎留言指導~ 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM