1. 程式人生 > >利用canvas畫一個動態時鐘

利用canvas畫一個動態時鐘

目標:利用canvas畫布畫一個動態時鐘,根據目前的時間可以實時更新的,可以在過程中新增一些效果,比如讓時鐘外圍的一圈顏色漸變,時鐘上的數字顏色改變,時鐘的指標顏色改變。。。

設定一個定時器

先放上一張效果圖,參考一下

先建一個畫布,寫好樣式

<style type="text/css">
*{
margin: 0;
padding: 0;
}
div{    //設定div的text-align為center,margin-top
text-align: center;
margin-top: 150px;
}
canvas{    //設定一下畫布的邊框
border: 1px solid #000;
}
</style>

<div>    //設定一下畫布的寬高
<canvas id="canvas" width="500px" height="500px"></canvas>
</div>

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");      //畫布一般都是2d的

var width = canvas.width;          //時鐘的寬高等於畫布的寬高,設定時鐘的半徑為畫布的一半,這樣時鐘就可以包含在畫布裡面
var height = canvas.height;

var r = height/2;

//接下來開始準備畫圓,畫圓的時候給圓加了漸變色,根據個人喜好,漸變色加在其他地方也可以,本人是把漸變色加在了這裡

var r1 = Math.floor(Math.random()*256);    //讓顏色隨機,重新整理一下就可以變其他的顏色
var g1 = Math.floor(Math.random()*256);
var b1 = Math.floor(Math.random()*256);
var grd=ctx.createLinearGradient(0,0,0,r);

//函式

ctx.save()      //儲存
ctx.translate(r,r);      
ctx.beginPath();                //開始路徑
ctx.arc(0,0,r-5,0,Math.PI*2,false);        //畫圓(原點座標,半徑設定的可以少一些,因為要加上框的大小,讓圓在畫布的寬高裡面,整個圓,方向設定為順時針,逆時針都可以)
ctx.closePath();                //關閉路徑
ctx.lineWidth = 10;               //設定圓的線寬為10
grd.addColorStop(0,"rgb("+r1+","+g1+","+b1+")");    //設定的漸變色,可以設定的細膩一點,這裡我是從0-0.25-0.5-0.75-1設定的
grd.addColorStop(0.25,"rgb("+b1+","+g1+","+r1+")");
grd.addColorStop(0.5,"rgb("+g1+","+b1+","+r1+")");
grd.addColorStop(0.75,"rgb("+g1+","+b1+","+r1+")");
grd.addColorStop(1,"rgb("+g1+","+b1+","+r1+")");
ctx.strokeStyle=grd;            //漸變色
ctx.stroke();      //

 //下面開始新增時鐘上面的數字,圓一般是從0也就是時鐘的指標3那裡開始,把這些數字放在一個數組裡面,設定一下數字的字型大小,樣式,

var hoursnum = [3,4,5,6,7,8,9,10,11,12,1,2];
ctx.font = "20px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";

 //下面開始設定時鐘上數字的顏色

for(var i = 0;i < hoursnum.length;i++){
var rad = 2 * Math.PI / 12 * i;      //一整個圓,一共有12個數字,算出數字所在位置的弧度
var x = Math.cos(rad) * (r - 30);    //判斷數字的座標,例如數字4,x=cos30度,y=sin30度,
var y = Math.sin(rad) * (r - 30);
ctx.fillText(hoursnum[i],x,y)          
ctx.fillStyle = "red";          //可以設定一下顏色,在此處我設定的紅色
}

//現在開始設定數字之間的小間隙,此處實際上代表的是分的顏色

for(var j = 0;j < 60;j++){
var rad = 2 * Math.PI / 60 * j;
var x = Math.cos(rad) * (r - 15);
var y = Math.sin(rad) * (r - 15);
ctx.beginPath();         //開始路徑
if(j % 5 === 0){
ctx.fillStyle = "lightpink";     //把間隙之間的顏色判斷一下,設定不同的顏色,容易分辨
}else{
ctx.fillStyle = "darkred"
}
ctx.arc(x,y,2,0,Math.PI*2)
ctx.closePath();        //結束路徑
ctx.fill()
}

//設定時針

ctx.save();
ctx.beginPath();
ctx.lineWidth = 6;
var rad = Math.PI * 2 / 12 * hour;
var rad_minu = Math.PI * 2 / 12 / 60 * minu;    //分針對時針會有影響,設定一下,消除分針對時針的影響
ctx.rotate(rad + rad_minu);
ctx.moveTo(0,10);
ctx.lineTo(0,-r/2);
ctx.lineCap="round";    //使用linecap屬性給兩端稍加一點弧度,看起來不是那麼生硬
ctx.strokeStyle = "darkred";
ctx.stroke()
ctx.restore()

//設定分針

ctx.save();
ctx.beginPath();
ctx.lineWidth = 4;
var rad = Math.PI * 2 / 60 * minu;
ctx.rotate(rad)
ctx.moveTo(0,10);
ctx.lineTo(0,-r+50);
ctx.lineCap="round";
ctx.strokeStyle = "#F0f101";
ctx.stroke()
ctx.restore()

//設定秒針

ctx.save();
var rad = Math.PI * 2 / 60 * seco;
ctx.beginPath();
ctx.rotate(rad)
ctx.fillStyle = "pink";
ctx.moveTo(-2,20);
ctx.lineTo(2,20);
ctx.lineTo(1,-r+20);
ctx.lineTo(-1,-r+20);
ctx.closePath()
ctx.fill()
ctx.restore()

//設定一個圓,把時針,分針,秒針固定著,看起來視覺效果好一些

ctx.beginPath();
ctx.fillStyle = "#f00";      //記得設定一個顏色
ctx.arc(0,0,5,0,Math.PI*2);
ctx.closePath();
ctx.fill()

//設定定時器,呼叫上面的時針,分針,秒針的函式

function draw(){
ctx.clearRect(0,0,width,height);
var datenow = new Date();
var hour = datenow.getHours();
var minu = datenow.getMinutes();
var seco = datenow.getSeconds();

fun()
drawHour(hour,minu)
drawMinu(minu)
drawSeco(seco)
drawDot()
ctx.restore()
}
draw()
setInterval(draw,1000)

此處附上程式碼

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>時鐘</title>
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
            }
            div{
                text-align: center;
                margin-top: 150px;
            }
            canvas{
                border: 1px solid #000;
            }
        </style>
    </head>
    <body>
        <div>
            <canvas id="canvas" width="500px" height="500px"></canvas>
        </div>
        <script type="text/javascript">
            var canvas = document.getElementById("canvas");
            var ctx = canvas.getContext("2d");
            var width = canvas.width;
            var height = canvas.height;
            var r = height/2;
            var r1 = Math.floor(Math.random()*256);
            var g1 = Math.floor(Math.random()*256);
            var b1 = Math.floor(Math.random()*256);
            var grd=ctx.createLinearGradient(0,0,0,r);
            
            function fun(){
                ctx.save()
                ctx.translate(r,r);
                ctx.beginPath();
                ctx.arc(0,0,r-5,0,Math.PI*2,false);
                ctx.closePath();
                ctx.lineWidth = 10;
                grd.addColorStop(0,"rgb("+r1+","+g1+","+b1+")");
                grd.addColorStop(0.25,"rgb("+b1+","+g1+","+r1+")");
                grd.addColorStop(0.5,"rgb("+g1+","+b1+","+r1+")");
                grd.addColorStop(0.75,"rgb("+g1+","+b1+","+r1+")");
                grd.addColorStop(1,"rgb("+g1+","+b1+","+r1+")");
                ctx.strokeStyle=grd;
                ctx.stroke();
                
                var hoursnum = [3,4,5,6,7,8,9,10,11,12,1,2];
                ctx.font = "20px Arial";
                ctx.textAlign = "center";
                ctx.textBaseline = "middle";
                
                for(var i = 0;i < hoursnum.length;i++){
                    var rad = 2 * Math.PI / 12 * i;   
                    var x = Math.cos(rad) * (r - 30);
                    var y = Math.sin(rad) * (r - 30);
                    ctx.fillText(hoursnum[i],x,y)
                    ctx.fillStyle = "red";
                }
                
                for(var j = 0;j < 60;j++){
                    var rad = 2 * Math.PI / 60 * j;   
                    var x = Math.cos(rad) * (r - 15);
                    var y = Math.sin(rad) * (r - 15);
                    ctx.beginPath();            
                    if(j % 5 === 0){
                        ctx.fillStyle = "darkred";    
                    }else{
                        ctx.fillStyle = "lightpink"
                    }
                    ctx.arc(x,y,2,0,Math.PI*2)
                    ctx.closePath();
                    ctx.fill()
                }
                
            }
            function drawHour(hour,minu){
                ctx.save();     
                ctx.beginPath();
                ctx.lineWidth = 6;
                var rad = Math.PI * 2 / 12 * hour;
                var rad_minu = Math.PI * 2 / 12 / 60 * minu;
                ctx.rotate(rad + rad_minu);
                ctx.moveTo(0,10);
                ctx.lineTo(0,-r/2);
                ctx.lineCap="round";
                ctx.strokeStyle = "darkred";
                ctx.stroke()
                ctx.restore()  
            }
            
            function drawMinu(minu){
                ctx.save();     
                ctx.beginPath();
                ctx.lineWidth = 4;
                var rad = Math.PI * 2 / 60 * minu;
                ctx.rotate(rad)
                ctx.moveTo(0,10);
                ctx.lineTo(0,-r+50);
                ctx.lineCap="round";
                ctx.strokeStyle = "#F0f101";
                ctx.stroke()
                ctx.restore()   
            }
            function drawSeco(seco){
                ctx.save();     
                var rad = Math.PI * 2 / 60 * seco;
                ctx.beginPath();
                ctx.rotate(rad)
                ctx.fillStyle = "pink";
                ctx.moveTo(-2,20);
                ctx.lineTo(2,20);
                ctx.lineTo(1,-r+20);
                ctx.lineTo(-1,-r+20);
                ctx.closePath()
                ctx.fill()
                ctx.restore()   
            }
            
            function drawDot(){
                ctx.beginPath();
                ctx.fillStyle = "#f00";
                ctx.arc(0,0,5,0,Math.PI*2);
                ctx.closePath();
                ctx.fill()
            }
            
            function draw(){
                ctx.clearRect(0,0,width,height);
                var datenow = new Date();
                var hour = datenow.getHours();
                var minu = datenow.getMinutes();
                var seco = datenow.getSeconds();
                
                fun()
                drawHour(hour,minu)
                drawMinu(minu)
                drawSeco(seco)
                drawDot()
                ctx.restore()
            }
            draw()
            setInterval(draw,1000)
        </script>
    </body>
</html>