Canvas入門-利用Canvas繪制好玩的電子時鐘

在這之前

你需要了解一下方法的使用:

  • beginPath()
  • closePath()
  • moveTo()
  • lineTo()
  • fill()
  • stroke()
  • fillRect()
  • clearRect()

這些我在前面的文章介紹過毡泻,可以看:

canvas入門-利用 canvas 制作一個七巧板

畫個圓

arc()方法

arc(x, y, radius, startAngle, endAngle, anticlockwise)

= > 畫一個以(x,y)為圓心的以radius為半徑的圓挥悼獭(圓)蓝牲,從startAngle開始到endAngle結(jié)束粱栖,按照anticlockwise給定的方向(默認(rèn)為順時針)來生成。
該方法有五個參數(shù):x,y為繪制圓弧所在圓上的圓心坐標(biāo)太颤。radius為半徑谨垃。startAngle以及endAngle參數(shù)用弧度定義了開始以及結(jié)束的弧度幌甘。這些都是以x軸為基準(zhǔn)。參數(shù)anticlockwise 為一個布爾值蚁飒。為true時动壤,是逆時針方向,否則順時針方向淮逻。

注意:arc()函數(shù)中的角度單位是弧度琼懊,不是度數(shù)。角度與弧度的js表達(dá)式:radians=(Math.PI/180)*degrees爬早。

//畫一個帶邊框的實(shí)心圓
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 600;
ctx.beginPath();
var x = 200, // x 坐標(biāo)值
    y = 200, // y 坐標(biāo)值
    radius = 50, //半徑
    startAngle = 0 ; //開始點(diǎn)
    endAngle = Math.PI * 2; //結(jié)束點(diǎn)
    anticlockwise = true; //逆時針 
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
ctx.lineWidth = 10;
ctx.fillStyle = "#1208ff";
ctx.strokeStyle = "#333";
ctx.stroke();
ctx.fill();

實(shí)現(xiàn)的效果圖如下:


cricle.png

準(zhǔn)備工作

會畫個圓之后呢哼丈,就要開始繪制我們的電子時鐘。開始之前筛严,我們需要理清思路醉旦。首先,我們要創(chuàng)建個二維數(shù)組放置我們從0-9的點(diǎn)陣圖形,當(dāng)元素的值為1的時候车胡,就要將其繪制出來檬输。以下是二維數(shù)組的片段:

[
    [0,0,1,1,1,0,0],
    [0,1,1,0,1,1,0],
    [1,1,0,0,0,1,1],
    [1,1,0,0,0,1,1],
    [1,1,0,0,0,1,1],
    [1,1,0,0,0,1,1],
    [1,1,0,0,0,1,1],
    [1,1,0,0,0,1,1],
    [0,1,1,0,1,1,0],
    [0,0,1,1,1,0,0]
]//0

我們要做的就是將 0 - 9 個數(shù)字用二維數(shù)組表示出來。

繪制電子時鐘的數(shù)字

首先匈棘,我們要遍歷我們的二維數(shù)組丧慈,如果元素的值為 1 ,則我們就將他繪制成圓形主卫,那如何確定每個元素的圓心呢逃默,看下面這張圖:

確定圓心的坐標(biāo)

接著我們寫這樣一個繪制數(shù)字的函數(shù):

function drawNum(x, y, num, ctx){ 
    for (var i = 0; i < digit[num].length; i++){
        for(var j = 0; j < digit[num][i].length; j++){
            if( digit[num][i][j] == 1){
                ctx.beginPath();
                ctx.fillStyle = "rgb(0, 102, 153)";
                ctx.arc(x+(RADIUS+1)*2*j+(RADIUS+1), y+(RADIUS+1)*2*i+(RADIUS+1), RADIUS, 0, Math.PI*2);
                ctx.fill();
                ctx.closePath();
            }
        }
    }
}

然后,調(diào)用該函數(shù)來繪制我們的數(shù)字:

var RADIUS = 4; // 圓的半徑
drawNum(0, 0, 1, ctx);

繪制的效果如下:


1.png

)

繪制簡單的電子時鐘

我們需要定義一個函數(shù)draw()來繪制我們的電子時鐘簇搅。

function draw(ctx){
    var curDate = new Date();
    var hour = curDate.getHours();
    var minute = curDate.getMinutes();
    var seconds = curDate.getSeconds();
    drawNum(Margin_X, Margin_Y, parseInt(hour/10), ctx);
    drawNum(Margin_X + (RADIUS+1)*15, Margin_Y, parseInt(hour%10), ctx);
    drawNum(Margin_X + (RADIUS+1)*30, Margin_Y, 10, ctx);
    drawNum(Margin_X + (RADIUS+1)*45, Margin_Y, parseInt(minute/10), ctx);
    drawNum(Margin_X + (RADIUS+1)*60, Margin_Y, parseInt(minute%10), ctx);
    drawNum(Margin_X + (RADIUS+1)*75, Margin_Y, 10, ctx);
    drawNum(Margin_X + (RADIUS+1)*90, Margin_Y, parseInt(seconds/10), ctx);
    drawNum(Margin_X + (RADIUS+1)*105, Margin_Y, parseInt(seconds%10), ctx);
}

為了讓每個數(shù)字之間有些間隔笑旺,不重疊在一起,定義了兩個變量 Margin_XMargin_Y來控制它距畫布左邊和頂部的距離馍资。初始值都是30筒主;

var Margin_X = 30;  //  離 canvas 原點(diǎn)的坐標(biāo)值 x
var Margin_Y = 30;  //  離 canvas 原點(diǎn)的坐標(biāo)值 y

讓電子時鐘動起來

setInterval()方法

setInterval(function,time)

= > 該方法會循環(huán)執(zhí)行一個函數(shù),時間間隔為 time(ms)

我們利用 setInterval方法讓我們的電子時鐘動起來鸟蟹。

setInterval(function(){
        draw(ctx);
}, 500);

相應(yīng)的乌妙,我們需要在重復(fù)繪制前,清楚我們的畫布建钥,不然會導(dǎo)致數(shù)字重疊在一起藤韵。這里用到了clearRect()清楚我們的畫布。

ctx.clearRect(0,0,1024,786);

附上完整的代碼:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>canvas</title>
</head>
<body>
    <canvas id="canvas" width = "1024" height= "786" style="display: block; margin: 50px auto;" >
        當(dāng)前瀏覽器不支持canvas  
    </canvas>
<script src="digit.js"></script>
<script type="text/javascript">
//電子時鐘

var RADIUS = 4;  // 圓的半徑
var Margin_X = 30;  //  離 canvas 原點(diǎn)的坐標(biāo)值 x
var Margin_Y = 30;  //  離 canvas 原點(diǎn)的坐標(biāo)值 y

window.onload = function(){
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    setInterval(function(){
        draw(ctx);
    }, 500);
}

function draw(ctx){
    ctx.clearRect(0,0,1024,786);
    var curDate = new Date();
    var hour = curDate.getHours();
    var minute = curDate.getMinutes();
    var seconds = curDate.getSeconds();
    drawNum(Margin_X, Margin_Y, parseInt(hour/10), ctx);
    drawNum(Margin_X + (RADIUS+1)*15, Margin_Y, parseInt(hour%10), ctx);
    drawNum(Margin_X + (RADIUS+1)*30, Margin_Y, 10, ctx);
    drawNum(Margin_X + (RADIUS+1)*45, Margin_Y, parseInt(minute/10), ctx);
    drawNum(Margin_X + (RADIUS+1)*60, Margin_Y, parseInt(minute%10), ctx);
    drawNum(Margin_X + (RADIUS+1)*75, Margin_Y, 10, ctx);
    drawNum(Margin_X + (RADIUS+1)*90, Margin_Y, parseInt(seconds/10), ctx);
    drawNum(Margin_X + (RADIUS+1)*105, Margin_Y, parseInt(seconds%10), ctx);
}

function drawNum(x, y, num, ctx){
    for (var i = 0; i < digit[num].length; i++){
        for(var j = 0; j < digit[num][i].length; j++){
            if( digit[num][i][j] == 1){
                ctx.beginPath();
                ctx.fillStyle = "rgb(0, 102, 153)";
                ctx.arc(x+(RADIUS+1)*2*j+(RADIUS+1), y+(RADIUS+1)*2*i+(RADIUS+1), RADIUS, 0, Math.PI*2);
                ctx.fill();
                ctx.closePath();
            }
        }
    }
}
</script>
</body>
</html>

digit.js

digit =
    [
        [
            [0,0,1,1,1,0,0],
            [0,1,1,0,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,0,1,1,0],
            [0,0,1,1,1,0,0]
        ],//0
        [
            [0,0,0,1,1,0,0],
            [0,1,1,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [1,1,1,1,1,1,1]
        ],//1
        [
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,0,1,1,0,0,0],
            [0,1,1,0,0,0,0],
            [1,1,0,0,0,0,0],
            [1,1,0,0,0,1,1],
            [1,1,1,1,1,1,1]
        ],//2
        [
            [1,1,1,1,1,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,0,1,1,1,0,0],
            [0,0,0,0,1,1,0],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//3
        [
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,1,0],
            [0,0,1,1,1,1,0],
            [0,1,1,0,1,1,0],
            [1,1,0,0,1,1,0],
            [1,1,1,1,1,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,0,1,1,0],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,1,1]
        ],//4
        [
            [1,1,1,1,1,1,1],
            [1,1,0,0,0,0,0],
            [1,1,0,0,0,0,0],
            [1,1,1,1,1,1,0],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//5
        [
            [0,0,0,0,1,1,0],
            [0,0,1,1,0,0,0],
            [0,1,1,0,0,0,0],
            [1,1,0,0,0,0,0],
            [1,1,0,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//6
        [
            [1,1,1,1,1,1,1],
            [1,1,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,1,1,0,0,0],
            [0,0,1,1,0,0,0],
            [0,0,1,1,0,0,0],
            [0,0,1,1,0,0,0]
        ],//7
        [
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//8
        [
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,1,1,0,0,0,0]
        ],//9
        [
            [0,0,0,0],
            [0,0,0,0],
            [0,1,1,0],
            [0,1,1,0],
            [0,0,0,0],
            [0,0,0,0],
            [0,1,1,0],
            [0,1,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ]//:
    ];

實(shí)現(xiàn)的效果圖如下:


效果圖

甚至我們還可以這樣子:

嗚嗚嗚
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熊经,一起剝皮案震驚了整個濱河市泽艘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌镐依,老刑警劉巖匹涮,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異槐壳,居然都是意外死亡然低,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門务唐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雳攘,“玉大人,你說我怎么就攤上這事枫笛《置穑” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵刑巧,是天一觀的道長喧兄。 經(jīng)常有香客問我无畔,道長,這世上最難降的妖魔是什么繁莹? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任檩互,我火速辦了婚禮,結(jié)果婚禮上咨演,老公的妹妹穿的比我還像新娘闸昨。我一直安慰自己,他們只是感情好薄风,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布饵较。 她就那樣靜靜地躺著,像睡著了一般遭赂。 火紅的嫁衣襯著肌膚如雪循诉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼启涯。 笑死,一個胖子當(dāng)著我的面吹牛划纽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锌畸,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼勇劣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了潭枣?” 一聲冷哼從身側(cè)響起比默,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盆犁,沒想到半個月后命咐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚣抗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年侈百,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翰铡。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖讽坏,靈堂內(nèi)的尸體忽然破棺而出锭魔,到底是詐尸還是另有隱情,我是刑警寧澤路呜,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布迷捧,位于F島的核電站织咧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏漠秋。R本人自食惡果不足惜笙蒙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庆锦。 院中可真熱鬧捅位,春花似錦、人聲如沸搂抒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽求晶。三九已至焰雕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芳杏,已是汗流浹背矩屁。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爵赵,地道東北人吝秕。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像亚再,于是被迫代替她去往敵國和親郭膛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容