1. 程式人生 > >使用Canvas(畫布)完成一個時鐘

使用Canvas(畫布)完成一個時鐘

Canvas最初由蘋果推出,後來由W3C推廣,目前幾乎所有瀏覽器都支援Canvas。

canvas是一個閉合標籤,包括寬度和高度屬性。預設值為寬300,高150。瀏覽器不支援canvas時,canvas的文字會顯示,通常用來檢測瀏覽器相容性。

<canvas id="can" width="300" height="300">您的瀏覽器不支援canvas</canvas>

canvas建立完了後,主要就依靠javascript完成它的功能了~

  1. 在<script></script>裡,首先找到指定畫布,然後建立2Dcontext物件。------這是寫canvas必須的步驟!
    var can = document.getElementById("can");
    var ctx = can2.getContext("2d");
  2. 開始寫繪製時鐘函式,function drawclock();
  3. 首先需要把儲存函式放在最前面。然後,由於開始的canvas的中心是在容器最左上角,而我們的時鐘圖需要以整個canvas的中央作為圓點,因此需要用translate(),使中心居中!然後由於,預設的canvas的方向是水平向右和垂直向下的,而我們希望時鐘的起始方向是x軸對著12點鐘方向所以要使中心再旋轉逆時針90度。以及設定線寬,線頭形狀和顏色。
    ctx.save();ctx.translate(150, 150);
    ctx.rotate(-Math.PI / 2);
    ctx.lineWidth = 6;
    ctx.strokeStyle = "blue";
    ctx.lineCap = "round";
  4. 下面寫錶盤刻度。分兩種刻度,時針、分針。時針的刻度。 一共有十二個時針的刻度,每個刻度就是30度。使用for迴圈迴圈12次。每次旋轉30度。每次的起點是(100,0),終點是(120,0),設定了起點終點和角度後就是用stroke()描邊。
    for (var i = 0; i < 12; i++) {
        ctx.beginPath();
        ctx.rotate(Math.PI / 6);
        ctx.moveTo(100, 0);
        ctx.lineTo(120, 0);
        ctx.stroke();
    }     注意,這裡的迴圈第一句是beginpath(),它的作用就是迴圈每執行完一次,context回到原點處。這一句不要忘了
    

     同樣的,對於分針,就是60個刻度,每個刻度就是6度。為了區分,設定線寬比時針的線寬小一點,長度也短一點,顏色也選個不一樣的。

for (var k = 0; k < 60; k++) {
    ctx.strokeStyle = "red";
    ctx.beginPath();
    ctx.rotate(Math.PI / 30);
    ctx.moveTo(118, 0);
    ctx.lineTo(120, 0);
    ctx.stroke();
}

5.刻度寫好了,接下來就是確定,隨著時間的推移,每一秒,我們的時針和分針、秒針應該停在哪個地方。

首先新建一個日期物件,獲取時、分、秒三個變數!

var time = new Date();
var s = time.getSeconds();
var m = time.getMinutes();
var h = time.getHours();
if (h > 12) {
    h -= 12;
}  這裡有一個細節,因為系統時間是24h制,而我們的時鐘刻度,只有12H,因此,H>12時,h-=12.

時針的旋轉角度為

時針的角度=360/12*小時+360/12/60分鐘+360/12/60/60秒;
//                    換算成弧度
//                    時針的弧度= π/6*小時+π/360*分鐘+π/2160*秒

分針的角度

分針的角度=360/60*分鐘+360/60/60*秒
//                    分針的弧度 =π/30*分鐘+π/1800*秒

秒針的角度

 秒針的角度=360/60*秒
////                    秒針的弧度 =π/30*秒

秒針、分針、時針為了區別,它們的長度不一,起點也不一,就像我們日常中看到的那樣!

然後要用restore和save恢復和儲存之前的繪圖設定。

   ctx.save();
        ctx.lineWidth = 9;
        ctx.beginPath();
        ctx.rotate(h * (Math.PI / 6) + (Math.PI / 360) * m + (Math.PI / 21600) * s);
        ctx.moveTo(-20, 0);
        ctx.lineTo(80, 0);
        ctx.stroke();
        ctx.restore();
//                    分針的角度=360/60*分鐘+360/60/60*秒
//                    分針的弧度 =π/30*分鐘+π/1800*秒
        ctx.save();
        ctx.lineWidth = 7;
        ctx.beginPath();
        ctx.rotate((Math.PI / 30) * m + (Math.PI / 1800) * s);
        ctx.moveTo(-20, 0);
        ctx.lineTo(112, 0);
        ctx.stroke();
        ctx.restore();
//                    秒針的角度=360/60*秒
////                    秒針的弧度 =π/30*秒
        ctx.save();
        ctx.lineWidth = 6;
        ctx.strokeStyle = "green";
        ctx.beginPath();
        ctx.rotate((Math.PI / 30) * s);
        ctx.moveTo(-30, 0);
        ctx.lineTo(120, 0);
        ctx.stroke();
        ctx.restore();

6.需要在時鐘中央繪製一個圓點,先用beginpath()讓canvas回到起點,再選半徑為10,用fill填充,紅色。

ctx.beginPath();
ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
ctx.fillStyle = "yellow";
ctx.fill();
ctx.restore();

7.到此,好像該做的都做完了。其實不然,這樣只能得到一個你開啟頁面時刻的時鐘圖,要實現動態的時鐘,需要每秒重新整理,這就需要用setInterval()函式的功能,每1000ms,執行一次drawclock()函式,這樣就每一秒畫一次,顯示的就是時鐘啦!

setInterval("drawclock()",1000);

大功告成!!

覺得講清楚的小夥伴請轉發、點贊、支援!

完整程式碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>practice</title>
    <style>
        canvas{
            border: 2px solid red;
        }
    </style>
</head>
<body >

<h3 >手繪時鐘</h3>
<canvas id="can2" width="300" height="300">您的瀏覽器不支援canvas</canvas>
<script>
    var can2 = document.getElementById("can2");
    var ctx = can2.getContext("2d");
    drawclock(); //此處先引用函式是為了防止載入完頁面的第一秒有空白畫面。
    function drawclock() {
        ctx.save();
        ctx.clearRect(0,0,300,300);
        ctx.translate(150, 150);
        ctx.rotate(-Math.PI / 2);
        ctx.lineWidth = 6;
        ctx.strokeStyle = "blue";
        ctx.lineCap = "round";
        for (var i = 0; i < 12; i++) {
            ctx.beginPath();
            ctx.rotate(Math.PI / 6);
            ctx.moveTo(100, 0);
            ctx.lineTo(120, 0);
            ctx.stroke();
        }
        for (var k = 0; k < 60; k++) {
            ctx.strokeStyle = "red";
            ctx.beginPath();
            ctx.rotate(Math.PI / 30);
            ctx.moveTo(118, 0);
            ctx.lineTo(120, 0);
            ctx.stroke();
        }
        var time = new Date();
        var s = time.getSeconds();
        var m = time.getMinutes();
        var h = time.getHours();
        if (h > 12) {
            h -= 12;
        }
//                    時針的角度=360/12*小時+360/12/60分鐘+360/12/60/60秒;
//                    換算成弧度
//                    時針的弧度= π/6*小時+π/360*分鐘+π/2160*秒
        ctx.save();
        ctx.lineWidth = 9;
        ctx.beginPath();
        ctx.rotate(h * (Math.PI / 6) + (Math.PI / 360) * m + (Math.PI / 21600) * s);
        ctx.moveTo(-20, 0);
        ctx.lineTo(80, 0);
        ctx.stroke();
        ctx.restore();
//                    分針的角度=360/60*分鐘+360/60/60*秒
//                    分針的弧度 =π/30*分鐘+π/1800*秒
        ctx.save();
        ctx.lineWidth = 7;
        ctx.beginPath();
        ctx.rotate((Math.PI / 30) * m + (Math.PI / 1800) * s);
        ctx.moveTo(-20, 0);
        ctx.lineTo(112, 0);
        ctx.stroke();
        ctx.restore();
//                    秒針的角度=360/60*秒
////                    秒針的弧度 =π/30*秒
        ctx.save();
        ctx.lineWidth = 6;
        ctx.strokeStyle = "green";
        ctx.beginPath();
        ctx.rotate((Math.PI / 30) * s);
        ctx.moveTo(-30, 0);
        ctx.lineTo(120, 0);
        ctx.stroke();
        ctx.restore();
//                    在鐘錶中心繪製一個圓點.
        ctx.beginPath();
        ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
        ctx.fillStyle = "yellow";
        ctx.fill();
        ctx.restore();
    }
    setInterval("drawclock()",1000);
</script>
</body>
</html>