用Canvas繪制自己的時(shí)鐘

這次我通過(guò)用Canvas實(shí)現(xiàn)一個(gè)時(shí)鐘來(lái),學(xué)習(xí)Canvas繪圖的基本API和用法,對(duì)于例子里面用到的每一個(gè)API,我都會(huì)詳細(xì)的列出它的用法。

首先來(lái)看一下繪制完成后的效果圖

時(shí)鐘.PNG

這個(gè)時(shí)鐘可以通過(guò)調(diào)整畫(huà)布的寬高來(lái)增大和縮小,效果不會(huì)有改變。

繪制的基本思路是

  • 時(shí)鐘背景圖的繪制
  • 時(shí)針、分針、秒針、原點(diǎn)的繪制
  • 讓時(shí)針、分針、秒針動(dòng)起來(lái)
時(shí)鐘背景圖的繪制

首先在HTML中定義一個(gè)寬高為400的畫(huà)布Canvas

<div>
       <canvas id="clock" height="400" width="400"></canvas>
   </div>

然后獲取畫(huà)布元素,定義畫(huà)布的執(zhí)行上下文ctx

/*獲取畫(huà)布元素*/
var dom = document.getElementById("clock");
/*獲得2d執(zhí)行環(huán)境*/
var ctx = dom.getContext('2d');

獲取畫(huà)布的寬高,以及定義時(shí)鐘的半徑

/*定義半徑為寬度的一半*/
var r = width/2;
/*縮放比例*/
var rem = width / 200;

接下來(lái)進(jìn)行背景圖的繪制,包括背景圓,12個(gè)數(shù)字,還有60個(gè)點(diǎn)的繪制,代碼如下,注釋已經(jīng)詳細(xì)說(shuō)明了過(guò)程

/*畫(huà)時(shí)鐘的背景圖*/
function drawBackground(){
    /*一開(kāi)始先把畫(huà)布的初始狀態(tài)保存下來(lái)*/
    ctx.save();
    /*將畫(huà)布的中心原點(diǎn)由(0,0)變成(r,r)*/
    ctx.translate(r,r);
    /*開(kāi)始繪畫(huà)*/
    ctx.beginPath();
    /*定義畫(huà)筆的寬度*/
    ctx.lineWidth = 10*rem;
    /*繪制一個(gè)圓*/
    ctx.arc(0,0,r-5*rem,0,2*Math.PI,false);
    /*進(jìn)行填充*/
    ctx.stroke();
    /*畫(huà)時(shí)鐘上的12個(gè)數(shù)字*/
    var hourNumber = [3,4,5,6,7,8,9,10,11,12,1,2];//12個(gè)小時(shí)數(shù)
    ctx.font = 18*rem +'px Arial';//定義字體大小和樣式
    ctx.textAlign='center';//將文本內(nèi)容居中對(duì)齊
    ctx.textBaseline='middle';//將文本基線設(shè)置為中線
    hourNumber.forEach(function(number,i){
        var rad = 2*Math.PI/12*i;//每個(gè)數(shù)字的弧度
        /*求出數(shù)字存放位置的x和y坐標(biāo)*/
        var x = Math.cos(rad)*(r - 30*rem);
        var y = Math.sin(rad)*(r - 30*rem);
        /*填充數(shù)字*/
        ctx.fillText(number,x,y);
    });
    /*繪制60個(gè)點(diǎn)*/
    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í)數(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();
    }
}

時(shí)針、分針、秒針、圓點(diǎn)的繪制

代碼如下

function drawHour(hour,minute){
    /*再次保存當(dāng)前畫(huà)布的狀態(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);//旋轉(zhuǎn)當(dāng)前繪畫(huà)
    ctx.lineWidth = 6*rem;
    ctx.lineCap = 'round';
    ctx.moveTo(0,10*rem);
    ctx.lineTo(0,-r/2);
    ctx.stroke();
    /*返回最近的一次SAVE的畫(huà)布狀態(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();
}

讓時(shí)鐘動(dòng)起來(lái)

function draw(){
    /*動(dòng)態(tài)改變的時(shí)候,每一次都要先將之前的矩形畫(huà)布清除掉,然后重新繪制*/
    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);//小時(shí)
    drawMinute(minute);//分鐘
    drawSecond(second);//秒
    drawDot();//中心原點(diǎn)
    /*恢復(fù)到一開(kāi)始save的那個(gè)畫(huà)布狀態(tài),進(jìn)行重新繪制*/
    ctx.restore();
}
draw();
setInterval(draw,1000);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容