context
arc画弧线
context.arc(300,300,200,0,0.5*Math.pi*(i+1)/10)表示以300,300为圆心
200为半径,0到1.5pi,第六个参数指定为顺时针还是逆时针(true)
//beginPath和closePath
倒计时程序:
数字用10*7的二维数组,冒号用10*4
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] ]//: ];
countDown.js
//获取浏览器的宽度和高度 //这里需要设置body和canvas的高度为100% var WINDOW_WIDTH=document.body.clientWidth; var WINDOW_HEIGHT=document.body.clientHeight; var MARGIN_LEFT=Math.round(WINDOW_WIDTH/10); var MARGIN_TOP=Math.round(WINDOW_HEIGHT/5); var RADIUS=Math.round(WINDOW_WIDTH*4/5/108)-1; //设置结束时间 //这里月份的设置,默认是从0-11的,所以九月份就是8 var ENDTIME=new Date(); ENDTIME.setTime(ENDTIME.getTime()+3600*1000*24*2); var curShowTimeSeconds=0; var balls = []; //设置小球可能出现的颜色 const colors = ["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"]; window.onload=function(){ var canvas=document.getElementById("canvas"); var ctx=canvas.getContext('2d'); canvas.width=WINDOW_WIDTH; canvas.height=WINDOW_HEIGHT; //获取当前显示的时间对应的秒数 curShowTimeSeconds=getCurrentShowTimeSeconds(); setInterval(function(){ //绘制 render(ctx); //更新 updates(); },50); } function getCurrentShowTimeSeconds(){ //获取当前时间 var curTime=new Date(); //返回结束时间对应的毫秒数减去当前时间的毫秒数的结果 var ret=ENDTIME.getTime()-curTime.getTime(); //把毫秒数转换成秒,并转换成整数 ret=Math.round(ret/1000); return ret>0?ret:0; } //更新页面 function updates(){ var nextShowTimeSecond=getCurrentShowTimeSeconds(); var nextHours=parseInt(nextShowTimeSecond/3600); var nextMinutes=parseInt((nextShowTimeSecond-nextHours*3600)/60); var nextSeconds=parseInt(nextShowTimeSecond%60); var curHours=parseInt(curShowTimeSeconds/3600); var curMinutes=parseInt((curShowTimeSeconds-curHours*3600)/60); var curSeconds=parseInt(curShowTimeSeconds%60); //判断当前秒数和下一秒秒数是否相等 if(nextSeconds!=curSeconds){ if( parseInt(curHours/10) != parseInt(nextHours/10) ){ addBalls( MARGIN_LEFT + 0 , MARGIN_TOP , parseInt(curHours/10) ); } if( parseInt(curHours%10) != parseInt(nextHours%10) ){ addBalls( MARGIN_LEFT + 16*(RADIUS+1) , MARGIN_TOP , parseInt(curHours%10) ); } if( parseInt(curMinutes/10) != parseInt(nextMinutes/10) ){ addBalls( MARGIN_LEFT + 40*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes/10) ); } if( parseInt(curMinutes%10) != parseInt(nextMinutes%10) ){ addBalls( MARGIN_LEFT + 56*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes%10) ); } if( parseInt(curSeconds/10) != parseInt(nextSeconds/10) ){ addBalls( MARGIN_LEFT + 80*(RADIUS+1) , MARGIN_TOP , parseInt(curSeconds/10) ); } if( parseInt(curSeconds%10) != parseInt(nextSeconds%10) ){ addBalls( MARGIN_LEFT + 96*(RADIUS+1) , MARGIN_TOP , parseInt(nextSeconds%10) ); } curShowTimeSeconds=nextShowTimeSecond; } updateBalls(); } function updateBalls(){ 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; if( balls[i].y >= WINDOW_HEIGHT-RADIUS ){ balls[i].y = WINDOW_HEIGHT-RADIUS; balls[i].vy = - balls[i].vy*0.6; } } //对页面进行性能优化 var cnt=0; for (var i=0;i<balls.length;i++) { if(balls[i].x+RADIUS>0&&balls[i].x-RADIUS<WINDOW_WIDTH){ balls[cnt++]=balls[i]; } } while(balls.length>cnt){ //删除数组中的内容 balls.pop(); } } function addBalls(x,y,num){ 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 ){ var aBall = { x:x+j*2*(RADIUS+1)+(RADIUS+1), y:y+i*2*(RADIUS+1)+(RADIUS+1), g:1.5+Math.random(), vx:Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4, vy:-5, color: colors[ Math.floor( Math.random()*colors.length ) ] }; balls.push( aBall ) ; } } } } function render(ctx){ //清除之前画的内容 ctx.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT); var hours=parseInt(curShowTimeSeconds/3600); var minutes=parseInt((curShowTimeSeconds-hours*3600)/60); var seconds=parseInt(curShowTimeSeconds%60); //小时的绘制 //设置允许空格 renderDigit(MARGIN_LEFT,MARGIN_TOP,parseInt(hours/10),ctx); //x、y的位置为加上第一个数字占用的空间,加1是为了留下一定的空格 renderDigit(MARGIN_LEFT+16*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),ctx); renderDigit(MARGIN_LEFT+32*(RADIUS+1),MARGIN_TOP,10,ctx); //分钟的绘制 renderDigit(MARGIN_LEFT+40*(RADIUS+1),MARGIN_TOP,parseInt(minutes/10),ctx); renderDigit(MARGIN_LEFT+56*(RADIUS+1),MARGIN_TOP,parseInt(minutes%10),ctx); renderDigit(MARGIN_LEFT+72*(RADIUS+1),MARGIN_TOP,10,ctx); //秒钟的绘制 renderDigit(MARGIN_LEFT+80*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10),ctx); renderDigit(MARGIN_LEFT+96*(RADIUS+1),MARGIN_TOP,parseInt(seconds%10),ctx); //绘制弹跳的小球 for( var i = 0 ; i < balls.length ; i ++ ){ ctx.fillStyle=balls[i].color; ctx.beginPath(); ctx.arc( balls[i].x , balls[i].y , RADIUS , 0 , 2*Math.PI , true ); ctx.closePath(); ctx.fill(); } } //绘制时分秒的数字 function renderDigit(x,y,num,ctx){ ctx.fillStyle="rgb(0,102,153)"; //循环digit数组里面的数据 //循环digit[0],则表示digit里面的第一个数组 //digit[0]也是一个数组,他的长度是10 for (var i=0;i<digit[num].length;i++) { //循环digit[0]第i个数组的长度 for (var j=0;j<digit[num][i].length;j++) { //如果数字是1的话则绘制一个圆 if(digit[num][i][j]==1){ ctx.beginPath(); ctx.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); } } } }index.html
<!DOCTYPE html> <html style="height: 100%"> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body style="height:100%;width: 100%;"> <canvas id="canvas" style="height:100%"> 当前浏览器不支持Canvas,请更换浏览器后再试 </canvas> <script src="digit.js"></script> <script src="countdown.js"></script> </body> </html>
本文详细介绍了如何利用HTML5的canvas元素来绘制一个倒计时数字钟。通过context.arc方法画出弧线构成钟面,并利用beginPath和closePath控制路径绘制数字。倒计时程序中,数字被表示为10*7的二维数组,冒号则用10*4的尺寸。核心代码分别在digit.js和countDown.js中实现。
1926

被折叠的 条评论
为什么被折叠?



