html5入門:教你用canvas寫一個時鍾


  今天的時間比較充裕,心血來潮,為大家分享一個html5的小例子,希望對剛學html5或者是沒學html5正准備學的“童鞋們”展示一個小案例,希望對你們的學習有幫助!高手嘛!請跳過吧!

  好了,閑話少數,先看看一下我們的案例效果圖吧!

  

  哦哦,我的時間暴露了!效果很粗糙,沒有美化,有興趣的朋友可以寫的好看一點!

  好了, 這是用什么寫的呢,這大家都知道,肯定是html5 的canvas標簽和js共同完成的啦,利用canvas的繪圖的屬性畫一個一個的形狀,現在就跟我一起畫吧!

  分析:時鍾包括  表盤,小時刻度,分鍾刻度,時針,分針,秒針

  首先當然是html5聲明,聲明很簡單,就一行:

  

<!doctype html>

  doctype可與的大寫,也可以是小寫,也可以是大小寫,這都無所謂,看你自己的習慣(不區分大小寫);頭部我就不寫了,我會將源碼附到下面,為節約時間,我就開始講正文,頭部也沒什么好將的

  

<canvas width="500" height="500" style="background:yellow; margin:50px auto; display:block; " id="clock">
     您的瀏覽器當前版本不支持canvas表簽
</canvas>

  在body里面寫一個canvas標簽,設置寬高為500,500(ps:設置寬高時建議按照上面的寫法給,不是說在樣式表里面不能給,在樣式表里面給寬高,在繪圖時圖形的位置會出錯),背景顏色設為黃色;

開始繪圖了:

<script>
    //獲取畫布DOM 還不可以操作
    var canvas = document.getElementById('canvas');
    //設置繪圖環境
    var cxt = canvas.getContext('2d');
</script>

先獲取canvas DOM, 設置繪圖環境,目前還只有2d;
(為節省版面,js部分拆分的部分不加script標記了)

畫表盤:

//表盤(藍色)
cxt.beginPath();  //畫筆開始
cxt.lineWidth = 5;  //設置畫筆的線寬
cxt.strokeStyle="blue";  //設置畫筆的顏色
cxt.arc(250,250,200,0,360,false);  //繪制圓形,坐標250,250 半徑200,整圓(0-360度),false表示順時針
cxt.stroke();   //繪圖
cxt.closePath();  //結束畫布

寫有注釋,看得懂不,解釋一下,畫形狀一般都需要寫一個開始畫筆和結束畫布,你自己寫一下,看看效果你就知道了,這是畫的空心圓,效果是這樣的:

然后我們開始畫刻度,刻度有小時刻度和分針刻度,先畫小時刻度吧:

//時針刻度
for(var i=0; i<12; i++){
cxt.save();   //設置旋轉環境
//設置時針的樣式
cxt.lineWidth=7;
cxt.strokeStyle="#000";

cxt.translate(250,250);//設置異次元空間的原點

cxt.rotate(30*Math.PI/180);//設置旋轉角度
cxt.beginPath();  //畫筆開始
cxt.moveTo(0,-170);   //畫線, 從坐標0,-170開始
cxt.lineTo(0,-190);   //到坐標0,-190結束
cxt.stroke();   //繪圖
cxt.closePath();
cxt.restore();  //將旋轉之后的元素放回原畫布
}


因為小時刻度是要在表盤上旋轉分布的,所以我們要設一個中心原點,以原點為中心,表針可以旋轉指向某個時刻,當然,刻度不只有一個,所以我們用for循環的方式,畫出12條線段,旋轉角度說明一下,弧度 = 角度*Math.PI/180,要是你有興趣,可以查一下這是怎么來的(數學里有),一周有12個刻度,一個刻度就是30°;

效果如圖:

畫分刻度,原理跟時刻的是一樣的,只是角度不一樣:

//分針刻度
for(var i=0; i<60;i++){
cxt.save();
cxt.lineWidth=5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-180);
cxt.lineTo(0,-190);
cxt.stroke();
cxt.closePath();
cxt.restore();    
}

注釋就不寫了,跟上面的是一樣的
效果如圖:

現在開始畫指針了,先畫時針吧:

//時針
cxt.save();  //設置旋轉環境
//時針樣式
cxt.lineWidth = 7;
cxt.strokeStyle="#000";
cxt.translate(250,250); //設置異次元空間原點
cxt.rotate(30*Math.PI/180);  //設置旋轉角度
cxt.beginPath();   //畫筆開始
cxt.moveTo(0,-140);  //畫線, 從坐標0,-140開始
cxt.lineTo(0,10);   //到坐標0,10結束
cxt.stroke();   //繪圖
cxt.closePath();   //結束畫布
cxt.restore();   //將旋轉之后的元素放回原畫布

時針現在實際上就是畫一個直線,因為要旋轉,所以是在異次元空間設置原點

效果如圖:

那分針和秒針就一樣一樣的了,稍微給點變化,比如給長一點,指針細一點

//分針
cxt.save();
//分針樣式
cxt.lineWidth = 5;
cxt.strokeStyle="#000";
cxt.translate(250,250);
cxt.rotate(6*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-160);
cxt.lineTo(0,15);
cxt.stroke();
cxt.closePath();
cxt.restore();

對照時針看注釋,這里就不寫注釋了
效果如圖:

現在寫分針:

//秒針
cxt.save();
cxt.lineWidth = 3;
cxt.strokeStyle="#f00";
cxt.translate(250,250);
cxt.rotate(60*Math.PI/180);
cxt.beginPath();
cxt.moveTo(0,-185);
cxt.lineTo(0,20);
cxt.stroke();
cxt.closePath();

效果如圖:

 

到此為止,這個時鍾的圖就畫出來了,就這樣就結束了嗎?這么丑,美化一下嘛!好吧,我們把分針稍微點綴一下!

//畫出時針,分針,秒針交叉點
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,0,5,0,360,false);
cxt.fillStyle="#fff";   //填充顏色
cxt.fill();     //填充
cxt.stroke();  
cxt.closePath();
            
//秒針裝飾
cxt.beginPath();
cxt.strokeStyle="#f00";
cxt.arc(0,-160,5,0,360,false);
cxt.fill();   //填充
cxt.stroke();
cxt.closePath();
cxt.restore();

說明一下:上一段是畫的3個指針交叉的地方,給點裝飾,見圖上,這樣顯得針是圍繞一個點轉的,fill()是填充的意思,相當於是畫一個實心圓,我們填充的是白色,外面的描邊是紅色,你可以這么理解,一個空心圓里面填充了一個白色,懂了吧;
下面的是分針指針尖山的一個小裝飾,跟前面的是一樣的,只是位置不一樣,但是這樣是不是更加“高端大氣上檔次”了;

效果如圖:

到這里就結束了嗎?好像不走耶,好吧,我們讓他動起來,動起來首先要知道時間,那我們就獲取一下本地的時間:

//獲取時間
var now = new Date();     //定義時間
var sec = now.getSeconds();  //獲取秒
var minute = now.getMinutes();   //獲取分鍾
var hour = now.getHours();    //獲取小時
//小時必須獲取浮點類型,產生偏移(小時+分鍾比)
hour = hour + minute/60;  
//將24小時轉換為12小時
hour=hour>12?hour-12:hour;

為什么要寫最后2行呢?解釋一下,最后一行是因為本地時間是24小時制,而我們的時鍾是12小時,所以我們要轉換一下,變成12小時;倒數第二行是,如果不加這行,時針只要沒有滿一個小時,指針一直指針整數刻度上的,而實際的鍾表不是這樣的,時針在不是整點的時候會有一點偏移,所以我們加的偏移量就是分針走的比例(大家有興趣可以試一下不加會是什么效果);

要動起來我們需要用到setInterval()函數,那我們將我們寫的代碼用一個函數包起來,這樣就簡潔了,但是不包含開始的2句,我們用drawClock()吧

function drawClock(){
    //獲取時間
    var now = new Date();   //定義時間
    var sec = now.getSeconds();  //獲取秒
    var minute = now.getMinutes();  //獲取分鍾
    var hour = now.getHours();   //獲取小時
    //小時必須獲取浮點類型,產生偏移(小時+分鍾比)
    hour = hour + minute/60;
    //將24小時轉換為12小時
    hour=hour>12?hour-12:hour;

    //表盤(藍色)
    cxt.beginPath();  //畫筆開始
    cxt.lineWidth = 5;  //設置畫筆的線寬
    cxt.strokeStyle="blue";  //設置畫筆的顏色
    cxt.arc(250,250,200,0,360,false);  //繪制圓形,坐標250,250 半徑200,整圓(0-360度),false表示順時針
    cxt.stroke();   //繪圖
    cxt.closePath();  //結束畫布
    //刻度
        //時針刻度
        for(var i=0; i<12; i++){
        cxt.save();
        //設置時針的樣式
                          cxt.lineWidth=7;
        cxt.strokeStyle="#000";
        //設置異次元空間原點
        cxt.translate(250,250);
        //設置旋轉角度
        cxt.rotate(i*30*Math.PI/180);
        cxt.beginPath();
        cxt.moveTo(0,-170); //畫線, 從坐標0,-170開始
        cxt.lineTo(0,-190); //到坐標0,-190結束
        cxt.stroke();
        cxt.closePath();
        cxt.restore();
        }
        //分針刻度
        for(var i=0; i<60;i++){
        cxt.save();
        cxt.lineWidth=5;
        cxt.strokeStyle="#000";
        cxt.translate(250,250);
        cxt.rotate(i*6*Math.PI/180);
        cxt.beginPath();
        cxt.moveTo(0,-180);
        cxt.lineTo(0,-190);
        cxt.stroke();
        cxt.closePath();
        cxt.restore();    
        }
                
    //時針
   cxt.save();
   //時針樣式
   cxt.lineWidth = 7;
   cxt.strokeStyle="#000";
   cxt.translate(250,250);
   cxt.rotate(/*hour**/30*Math.PI/180);
   cxt.beginPath();
   cxt.moveTo(0,-140);
   cxt.lineTo(0,10);
   cxt.stroke();
   cxt.closePath();
   cxt.restore();
            
   //分針
   cxt.save();
   //分針樣式
   cxt.lineWidth = 5;
   cxt.strokeStyle="#000";
   cxt.translate(250,250);
   cxt.rotate(/*minute**/6*Math.PI/180);
   cxt.beginPath();
   cxt.moveTo(0,-160);
   cxt.lineTo(0,15);
   cxt.stroke();
   cxt.closePath();
   cxt.restore();
            
   //秒針
   cxt.save();
   cxt.lineWidth = 3;
   cxt.strokeStyle="#f00";
   cxt.translate(250,250);
   cxt.rotate(/*sec**/60*Math.PI/180);
   cxt.beginPath();
   cxt.moveTo(0,-185);
   cxt.lineTo(0,20);
   cxt.stroke();
   cxt.closePath();
            
   //畫出時針,分針,秒針交叉點
   cxt.beginPath();
   cxt.strokeStyle="#f00";
   cxt.arc(0,0,5,0,360,false);
   cxt.fillStyle="#fff";   //填充顏色
   cxt.fill();   //填充
   cxt.stroke();
   cxt.closePath();
            
   //秒針裝飾
   cxt.beginPath();
   cxt.strokeStyle="#f00";
   cxt.arc(0,-160,5,0,360,false);
   cxt.fill();
   cxt.stroke();
   cxt.closePath();
   cxt.restore();
   }
   //使用setinterval();讓時鍾動起來
  
   setInterval(drawClock,1000);

ok,動起來,好,刷新,咦,沒有動耶,為什么呢,原來我們的指針都只是定義了一個角度,肯定懂不起來啦,好,我們將我們獲取的時間嫁到指針上

                
            //時針
            cxt.save();
            //時針樣式
            cxt.lineWidth = 7;
            cxt.strokeStyle="#000";
            cxt.translate(250,250);
            cxt.rotate(/*hour**/30*Math.PI/180);
            cxt.beginPath();
            cxt.moveTo(0,-140);
            cxt.lineTo(0,10);
            cxt.stroke();
            cxt.closePath();
            
            cxt.restore();
            
            //分針
            cxt.save();
            //分針樣式
            cxt.lineWidth = 5;
            cxt.strokeStyle="#000";
            cxt.translate(250,250);
            cxt.rotate(minute*6*Math.PI/180);
            cxt.beginPath();
            cxt.moveTo(0,-160);
            cxt.lineTo(0,15);
            cxt.stroke();
            cxt.closePath();
            
            cxt.restore();
            
            //秒針
            cxt.save();
            cxt.lineWidth = 3;
            cxt.strokeStyle="#f00";
            cxt.translate(250,250);
            cxt.rotate(sec*60*Math.PI/180);
            cxt.beginPath();
            cxt.moveTo(0,-185);
            cxt.lineTo(0,20);
            cxt.stroke();
            cxt.closePath();


看各指針旋轉角度的變化,不錯,被你找到了,那現在應該可以轉了吧,看圖

如圖所示:

哎呀,媽媽呀,這是什么怪物,怎么會這樣呢?你的是這樣嗎?是這樣就對了,原因是每一次指針旋轉都是畫上去的,走一步畫一步,就出現了像扇子一樣的東西,所以我們要在畫圖之前清空畫布,就是畫之前清掉前面畫的

cxt.clearRect(0,0,500,500); //清除畫布

這個是什么意思呢,實際上是2個坐標,0,0  和 500,500 對應整個畫布;

那這樣應該就萬事大吉了吧,刷新,嘖嘖,總覺得哪里不對勁,對,好像出來的時候慢了點,要等一會才出來,你的是這樣嗎,是這樣啊,是這樣 就對了,因為我們在他動之前讓他把表畫出來,所以執行setInterval()函數時需要1秒之后才開始畫,這就是為什么要等大概1秒針才出現的原因,解決方法,在setInterval()前執行drawClock()函數;

drawClock();
setInterval(drawClock,1000);

到這里,所有的問題就都解決了,你的時鍾動了沒,現在幾點了!

現在我把整個代碼附在下面,供大家參考學習:

<!doctype html>
<html>
    <head>
    <meta charset="utf-8">
    <title>canvas時鍾</title>
    </head>
<body>
        <canvas width="500" height="500" style="background:yellow; margin:50px auto; display:block; " id="clock">
            您的瀏覽器當前版本不支持canvas表簽
        </canvas>
        <script>
            var clock = document.getElementById("clock");
            var cxt = clock.getContext('2d');
            
            function drawClock(){
            cxt.clearRect(0,0,500,500); //清除畫布
            //獲取時間
            var now = new Date();   //定義時間
            var sec = now.getSeconds();  //獲取秒
            var minute = now.getMinutes();  //獲取分鍾
            var hour = now.getHours();   //獲取小時
            //小時必須獲取浮點類型,產生偏移(小時+分鍾比)
            hour = hour + minute/60;
            //將24小時轉換為12小時
            hour=hour>12?hour-12:hour;

            //表盤(藍色)
            cxt.beginPath();  //畫筆開始
            cxt.lineWidth = 5;  //設置畫筆的線寬
            cxt.strokeStyle="blue";  //設置畫筆的顏色
            cxt.arc(250,250,200,0,360,false);  //繪制圓形,坐標250,250 半徑200,整圓(0-360度),false表示順時針
            cxt.stroke();   //繪圖
            cxt.closePath();  //結束畫布
            //刻度
                //時針刻度
                for(var i=0; i<12; i++){
                    cxt.save();
                    //設置時針的樣式
                    cxt.lineWidth=7;
                    cxt.strokeStyle="#000";
                    //設置異次元空間原點
                    cxt.translate(250,250);
                    //設置旋轉角度
                    cxt.rotate(i*30*Math.PI/180);
                    cxt.beginPath();
                    cxt.moveTo(0,-170); //畫線, 從坐標0,-170開始
                    cxt.lineTo(0,-190); //到坐標0,-190結束
                    cxt.stroke();
                    cxt.closePath();
                    cxt.restore();
                }
                //分針刻度
                for(var i=0; i<60;i++){
                    cxt.save();
                    cxt.lineWidth=5;
                    cxt.strokeStyle="#000";
                    cxt.translate(250,250);
                    cxt.rotate(i*6*Math.PI/180);
                    cxt.beginPath();
                    cxt.moveTo(0,-180);
                    cxt.lineTo(0,-190);
                    cxt.stroke();
                    cxt.closePath();
                    cxt.restore();    
                }
                
            //時針
            cxt.save();
            //時針樣式
            cxt.lineWidth = 7;
            cxt.strokeStyle="#000";
            cxt.translate(250,250);
            cxt.rotate(hour*30*Math.PI/180);
            cxt.beginPath();
            cxt.moveTo(0,-140);
            cxt.lineTo(0,10);
            cxt.stroke();
            cxt.closePath();
            
            cxt.restore();
            
            //分針
            cxt.save();
            //分針樣式
            cxt.lineWidth = 5;
            cxt.strokeStyle="#000";
            cxt.translate(250,250);
            cxt.rotate(minute*6*Math.PI/180);
            cxt.beginPath();
            cxt.moveTo(0,-160);
            cxt.lineTo(0,15);
            cxt.stroke();
            cxt.closePath();
            
            cxt.restore();
            
            //秒針
            cxt.save();
            cxt.lineWidth = 3;
            cxt.strokeStyle="#f00";
            cxt.translate(250,250);
            cxt.rotate(sec*6*Math.PI/180);
            cxt.beginPath();
            cxt.moveTo(0,-185);
            cxt.lineTo(0,20);
            cxt.stroke();
            cxt.closePath();
            
            //畫出時針,分針,秒針交叉點
            cxt.beginPath();
            cxt.strokeStyle="#f00";
            cxt.arc(0,0,5,0,360,false);
            cxt.fillStyle="#fff";   //填充顏色
            cxt.fill();   //填充
            cxt.stroke();
            cxt.closePath();
            
            //秒針裝飾
            cxt.beginPath();
            cxt.strokeStyle="#f00";
            cxt.arc(0,-160,5,0,360,false);
            cxt.fill();
            cxt.stroke();
            cxt.closePath();
            cxt.restore();
        }
        //使用setinterval();讓時鍾動起來
        drawClock();
        setInterval(drawClock,1000);
        </script>
</body>
</html>


希望對大家的學習有幫助!

 

 

 

 

  


免責聲明!

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



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