JS+Canvas實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘效果
基于Canvas制作的動(dòng)態(tài)時(shí)鐘demo,供大家參考,具體內(nèi)容如下
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>動(dòng)態(tài)時(shí)鐘</title> <script type="text/javascript" src="js/lattice.js"></script> <script type="text/javascript" src="js/script.js"></script> <style type="text/css"> *{ padding: 0; margin: 0; } #canvasBox{ border-width: 2px; border-color: black; border-style: solid; width: 80%; margin: 0 auto; } </style> </head> <body> <!-- 將canvas放到一個(gè)盒子中,用盒子控制canvas的位置 --> <div id="canvasBox"> <canvas id="canvas"> 此瀏覽器不支持canvas </canvas> </div> </body> </html>
lattice.js
lattice = [ [ [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] ]//: ];
script.js
var CANVAS_WIDTH; var CANVAS_HEIGHT = 600; //設(shè)置點(diǎn)陣中圓的半徑 var RADIUS = 8; //設(shè)置時(shí)鐘距離邊框的位置 var MARGIN_LEFT = 100; var MARGIN_TOP = 40; //獲取初始狀態(tài)的時(shí)間 var time = new Date(); var hours = time.getHours(); var minutes = time.getMinutes(); var seconds = time.getSeconds(); //用于存儲(chǔ)小球?qū)ο? var balls = []; //小球顏色 var colors = ["red","orenge","yellow","green","blue","purple","pink"] window.onload = function(){ //獲得canvas外部盒子的寬度,使canvas與外部盒子寬度相同 var canvasBox = document.getElementById("canvasBox"); var boxWidth = getComputedStyle(canvasBox,null); CANVAS_WIDTH = parseInt(boxWidth.width); //設(shè)置canvas寬高并獲得畫(huà)筆對(duì)象 var canvas = document.getElementById("canvas"); canvas.width = CANVAS_WIDTH; canvas.height = CANVAS_HEIGHT; var context = canvas.getContext("2d"); //定時(shí)調(diào)用,50毫秒調(diào)用一次 setInterval(function(){ //繪制函數(shù) draw(context); },50); function draw(ctx){ //刷新屏幕 ctx.clearRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); //獲取當(dāng)前時(shí)間 var curTime = new Date(); var curHours = curTime.getHours(); var curMinutes = curTime.getMinutes(); var curSeconds = curTime.getSeconds(); //畫(huà)小時(shí) drawLattice(MARGIN_LEFT,MARGIN_TOP,parseInt(curHours/10),ctx); drawLattice(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10),ctx); //畫(huà)冒號(hào) drawLattice(MARGIN_LEFT+30*(RADIUS+1),MARGIN_TOP,10,ctx); //畫(huà)分鐘 drawLattice(MARGIN_LEFT+39*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes/10),ctx); drawLattice(MARGIN_LEFT+54*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes%10),ctx); //畫(huà)冒號(hào) drawLattice(MARGIN_LEFT+69*(RADIUS+1),MARGIN_TOP,10,ctx); //畫(huà)秒 drawLattice(MARGIN_LEFT+78*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds/10),ctx); drawLattice(MARGIN_LEFT+93*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds%10),ctx); //更新時(shí)間并繪制小球 update(context,curHours,curMinutes,curSeconds); //觀察小球數(shù)量 //console.log(balls.length); } //參數(shù): //x:繪制數(shù)字點(diǎn)陣的左上角的橫坐標(biāo) //y:繪制數(shù)字點(diǎn)陣的左上角的縱坐標(biāo) //num:要繪制的數(shù)字,實(shí)際上是lattice的索引,10表示冒號(hào) //ctx:畫(huà)筆 function drawLattice(x,y,num,ctx){ for(var i=0;i<lattice[num].length;i++){ for(var j=0;j<lattice[num][i].length;j++){ if(lattice[num][i][j]==1){ ctx.beginPath(); ctx.fillStyle = "blue"; ctx.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI); ctx.fill(); ctx.closePath(); } } } } //更新時(shí)間并繪制小球 function update(ctx,curHours,curMinutes,curSeconds){ if(seconds!=curSeconds){ //更新小時(shí) if(parseInt(curHours/10)!=parseInt(hours/10)){ addBalls(MARGIN_LEFT,MARGIN_TOP,parseInt(curHours/10)); } if(parseInt(curHours%10)!=parseInt(hours%10)){ addBalls(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10)); } //更新分鐘 if(parseInt(curMinutes/10)!=parseInt(minutes/10)){ addBalls(MARGIN_LEFT+39*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes/10)); } if(parseInt(curMinutes%10)!=parseInt(minutes%10)){ addBalls(MARGIN_LEFT+54*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes%10)); } //更新秒 if(parseInt(curSeconds/10)!=parseInt(seconds/10)){ addBalls(MARGIN_LEFT+78*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds/10)); } if(parseInt(curSeconds%10)!=parseInt(seconds%10)){ addBalls(MARGIN_LEFT+93*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds%10)); } //更新所有時(shí)間 hours = curHours; minutes = curMinutes; seconds = curSeconds; } //繪制小球 drawBalls(ctx); //更新小球運(yùn)動(dòng) updateBalls(); } //添加單個(gè)小球 //參數(shù): //x:小球的橫坐標(biāo) //y:小球的縱坐標(biāo) //num:變化的時(shí)間數(shù)字 function addBalls(x,y,num){ for(var i=0;i<lattice[num].length;i++){ for(var j=0;j<lattice[num][i].length;j++){ if(lattice[num][i][j]==1){ //添加一個(gè)小球?qū)ο? var ball = { //坐標(biāo) x:x+j*2*(RADIUS+1)+(RADIUS+1), y:y+i*2*(RADIUS+1)+(RADIUS+1), //重力加速度 g:1.5+Math.random(), //x、y方向的速度 vx:Math.pow(-1,Math.ceil(Math.random()*1000))*5, vy:-5, //小球顏色 color:colors[Math.floor(Math.random()*colors.length)] } //將小球添加進(jìn)儲(chǔ)存隊(duì)列中 balls.push(ball); } } } } //繪制小球 function drawBalls(ctx){ for(var i=0;i<balls.length;i++){ ctx.beginPath(); ctx.fillStyle = balls[i].color; ctx.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true); ctx.fill(); ctx.closePath(); } } //更新小球運(yùn)動(dòng) function updateBalls(){ //更新儲(chǔ)存數(shù)組中的小球的動(dòng)態(tài) for(var i=0;i<balls.length;i++){ balls[i].x += balls[i].vx; balls[i].y += balls[i].vy; balls[i].vy += balls[i].g; //邊緣碰撞檢測(cè) if(balls[i].y>=CANVAS_HEIGHT-RADIUS){ balls[i].y=CANVAS_HEIGHT-RADIUS; //模擬碰撞反彈和阻力 balls[i].vy=-balls[i].vy*0.6; } } //當(dāng)小球滾出畫(huà)布便可以從數(shù)組中刪除,以下是刪除算法 //儲(chǔ)存應(yīng)當(dāng)保留的小球的數(shù)量 var numBall = 0; for(var i=0;i<balls.length;i++){ if(balls[i].x+RADIUS>0&&balls[i].x-RADIUS<CANVAS_WIDTH){ //若判斷當(dāng)前小球在屏幕內(nèi),則將此小球盡量靠前,則每次循環(huán)后,數(shù)組最后面的小球就是滾出畫(huà)布的小球 balls[numBall] = balls[i]; numBall++; } } //從數(shù)組后面刪除小球 while(balls.length>numBall){ balls.pop(); } } };
效果圖:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript錯(cuò)誤處理超完整實(shí)用指南
在JavaScript中進(jìn)行錯(cuò)誤處理,最常見(jiàn)的方式就是使用try catch語(yǔ)句,下面這篇文章主要給大家介紹了關(guān)于JavaScript錯(cuò)誤處理的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11JavaScript控制網(wǎng)頁(yè)層收起和展開(kāi)效果的方法
這篇文章主要介紹了JavaScript控制網(wǎng)頁(yè)層收起和展開(kāi)效果的方法,涉及javascript操作網(wǎng)頁(yè)元素動(dòng)態(tài)效果的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04mui開(kāi)發(fā)中獲取單選按鈕、復(fù)選框的值(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇mui開(kāi)發(fā)中獲取單選按鈕、復(fù)選框的值(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07gulp-uglify 與gulp.watch()配合使用時(shí)報(bào)錯(cuò)(重復(fù)壓縮問(wèn)題)
gulp是基于Nodejs的自動(dòng)任務(wù)運(yùn)行器,gulp 和 grunt 非常類(lèi)似,但相比于 grunt 的頻繁 IO 操作,gulp 的流操作,能更快地更便捷地完成構(gòu)建工作。今天在學(xué)習(xí)gulp時(shí)遇到當(dāng)用gulp.watch來(lái)監(jiān)聽(tīng)js文件的變動(dòng)時(shí)出現(xiàn)重復(fù)壓縮問(wèn)題,下面小編給大家解答下2016-08-08JavaScript使用Canvas繪制一個(gè)驗(yàn)證碼組件
驗(yàn)證碼,這一日常伴隨我們的要素,是我們?cè)诰€(xiàn)交互的重要安全保障,你的手機(jī)短信里是否被它占據(jù)半壁江山,今天我們就來(lái)聊聊如何在網(wǎng)頁(yè)上實(shí)現(xiàn)一個(gè)簡(jiǎn)單的驗(yàn)證碼組件,需要的朋友可以參考下2023-09-09js與jQuery實(shí)現(xiàn)checkbox復(fù)選框全選/全不選的方法
這篇文章主要介紹了js與jQuery實(shí)現(xiàn)checkbox復(fù)選框全選/全不選的方法,結(jié)合實(shí)例較為詳細(xì)的分析了JavaScript與jQuery針對(duì)checkbox復(fù)選框全選與反選的操作技巧,需要的朋友可以參考下2016-01-01Bootstrap導(dǎo)航條學(xué)習(xí)使用(二)
這篇文章主要為大家詳細(xì)介紹了Bootstrap導(dǎo)航條的使用方法第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02