HTML5 canvas画布写炫彩动态的倒计时效果

html代码如下,插入了2个js代码。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>canvas</title>
 5 </head>
 6 <body>
 7     <canvas id="canvas" style="border-bottom:1px solid #1E90FF;margin:50px auto;display:block;" ></canvas>
 8 
 9 </body>
10 <script type="text/javascript" src="digit.js"></script>
11 <script type="text/javascript" src="countdown.js"></script>
12 <script type="text/javascript">
13 </script>
14 </html>
digit.js文件是,将数字用0,1表示的一个3维数组。
countdown.js文件是核心js文件,利用canvas画出时间图像和小球。
  1 /*
  2 ************************
  3 * powered by Ming
  4 * 2014-9-23
  5 ***********************
  6 */
  7 var CANVAS_WIDTH = 700;//画布宽度
  8 var CANVAS_HEIGHT = 450;
  9 var RADIUS = 5;//画布的中,圆点的半径
 10 
 11 var MARGIN_TOP = 60;
 12 var MARGIN_LEFT = 30;
 13 
 14 const endTime = new Date(2014,8,25,18,17,52);
 15 var curShowTimeSeconds = 0;
 16 
 17 var balls = [];
 18 const colors = ["#00FFFF","#A52A2A","#7FFF00","#DC143C","#00FFFF","#FF00FF","#FFD700","#4B0082"];
 19 
 20 window.onload = function(){
 21     var canvas = document.getElementById("canvas");
 22     var context = canvas.getContext("2d");
 23 
 24     canvas.width = CANVAS_WIDTH;
 25     canvas.height = CANVAS_HEIGHT;
 26 
 27     curShowTimeSeconds = getCurrentShowTimeSeconds();
 28 
 29     setInterval( function(){
 30         render( context );
 31         update();
 32 
 33     },50 );
 34 }
 35 
 36 function getCurrentShowTimeSeconds(){
 37 
 38     var curTime = new Date();
 39     var ret = endTime.getTime() - curTime.getTime();
 40     ret = Math.round( ret/1000 );
 41     return ret >= 0 ?ret : 0;
 42 }
 43 
 44 function update(){
 45     var nextShowTimeSeconds = getCurrentShowTimeSeconds();
 46 
 47     var nextHours = parseInt( nextShowTimeSeconds/3600 );
 48     var nextMinutes = parseInt( (nextShowTimeSeconds - nextHours*3600)/60 );
 49     var nextSeconds = nextShowTimeSeconds%60 ;
 50 
 51     var curHours = parseInt( curShowTimeSeconds/3600 );
 52     var curMinutes = parseInt( (curShowTimeSeconds - curHours*3600)/60 );
 53     var curSeconds = curShowTimeSeconds%60;
 54 
 55     //判断当时间改变时,产生小球
 56     if( nextSeconds != curSeconds ){
 57         //判断小时的2位数字是否变化
 58         if( parseInt(curHours/10) != parseInt(nextHours/10) )
 59             addBalls( MARGIN_LEFT+0, MARGIN_TOP, parseInt(curHours/10) );
 60         if( parseInt(curHours%10) != parseInt(nextHours%10) )
 61             addBalls( MARGIN_LEFT + 15*(RADIUS+1), MARGIN_TOP, parseInt(curHours%10) );
 62         //判断分钟
 63         if( parseInt(curMinutes/10) != parseInt(nextMinutes/10) )
 64             addBalls( MARGIN_LEFT+39*(RADIUS+1), MARGIN_TOP, parseInt(curMinutes/10) );
 65         if( parseInt(curMinutes%10) != parseInt(nextMinutes%10) )
 66             addBalls( MARGIN_LEFT + 54*(RADIUS+1), MARGIN_TOP, parseInt(curMinutes%10) );
 67         //判断秒钟
 68         if( parseInt(curSeconds/10) != parseInt(nextSeconds/10) )
 69             addBalls( MARGIN_LEFT+78*(RADIUS+1), MARGIN_TOP, parseInt(curSeconds/10) );
 70         if( parseInt(curSeconds%10) != parseInt(nextSeconds%10) )
 71             addBalls( MARGIN_LEFT + 93*(RADIUS+1), MARGIN_TOP, parseInt(curSeconds%10) );
 72 
 73         curShowTimeSeconds = nextShowTimeSeconds;
 74     }
 75 
 76     updateBalls();
 77     console.log( balls.length );
 78 }
 79 
 80 function updateBalls(){
 81 
 82     for( var i=0; i< balls.length;i++ ){
 83 
 84         balls[i].x += balls[i].vx;
 85         balls[i].y += balls[i].vy;
 86         balls[i].vy += balls[i].g
 87 
 88         if( balls[i].y >= CANVAS_HEIGHT - RADIUS ){
 89             balls[i].y = CANVAS_HEIGHT - RADIUS;
 90             balls[i].vy = - balls[i].vy*0.7;//设置摩擦因素
 91         }
 92     }
 93 
 94     //清除多余的小球,不在边框内的 ,优化性能
 95     var cnt = 0;
 96     for ( var i= 0;i< balls.length; i++ )
 97         if( balls[i].x + RADIUS >0 && balls[i].x - RADIUS < CANVAS_WIDTH )
 98             balls[cnt++] = balls[i];
 99 
100         while( balls.length > Math.min(700,cnt) )
101             balls.pop();
102 
103 }
104 
105 function addBalls( x,y,num ){
106 
107     for( var i = 0;i< digit[num].length ;i++ )
108         for( var j = 0; j< digit[num][i].length; j++ )
109             if( digit[num][i][j] == 1 ){
110 
111                 var aBall = {
112                     x: x+ j*2*(RADIUS+1)+(RADIUS+1),
113                     y: y+ i*2*(RADIUS+1)+(RADIUS+1),
114                     g: 1.5+Math.random(),
115                     vx:Math.pow( -1, Math.ceil( Math.random()*1000 )*11 ),
116                     vy:-5,
117                     color:colors[ Math.floor( Math.random()*colors.length ) ]
118                 };
119 
120                 balls.push( aBall );
121 
122             }
123 
124 }
125 
126 function render( cxt ){
127 
128     cxt.clearRect( 0,0,CANVAS_WIDTH,CANVAS_HEIGHT );//刷新画布
129 
130     //获取当前时间值
131     var hours = parseInt( curShowTimeSeconds/3600 );
132     var minutes = parseInt( (curShowTimeSeconds - hours*3600)/60 );
133     var seconds = parseInt( curShowTimeSeconds%60 );
134 
135     //parseInt() 解析一个字符串,并返回一个整数
136     //在画布中,每个数字是由7个小方格组成的,故有7个半径为14,增加一点距离则为15,
137     //而冒号是由4个组成,故为4个为8+1=9的距离间隔
138     renderDigit( MARGIN_LEFT + 0, MARGIN_TOP, parseInt(hours/10),cxt );
139     renderDigit( MARGIN_LEFT + 15*(RADIUS+1), MARGIN_TOP, parseInt(hours%10),cxt );
140     renderDigit( MARGIN_LEFT + 30*(RADIUS+1), MARGIN_TOP, 10,cxt );//添加冒号,在digit中冒号是第10个
141     renderDigit( MARGIN_LEFT + 39*(RADIUS+1), MARGIN_TOP, parseInt(minutes/10),cxt );
142     renderDigit( MARGIN_LEFT + 54*(RADIUS+1), MARGIN_TOP, parseInt(minutes%10),cxt );
143     renderDigit( MARGIN_LEFT + 69*(RADIUS+1), MARGIN_TOP, 10,cxt );//添加冒号,在digit中冒号是第10个
144     renderDigit( MARGIN_LEFT + 78*(RADIUS+1), MARGIN_TOP, parseInt(seconds/10),cxt );
145     renderDigit( MARGIN_LEFT + 93*(RADIUS+1), MARGIN_TOP, parseInt(seconds%10),cxt );
146 
147 
148     //给小球画颜色
149     for( var i = 0;i< balls.length;i++ ){
150         cxt.fillStyle = balls[i].color;
151 
152         cxt.beginPath();
153         cxt.arc( balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true );
154         cxt.closePath();
155 
156         cxt.fill();
157     }
158 
159 }
160 
161 function renderDigit( x,y,num,cxt ){
162 
163     cxt.fillStyle = "#1E90FF";
164 
165     for( var i = 0;i< digit[num].length ;i++ )
166         for( var j = 0; j< digit[num][i].length; j++ )
167             if( digit[num][i][j] == 1 ){
168                 cxt.beginPath();
169                 cxt.arc( x+j*2*(RADIUS+1)+(RADIUS+1) ,y+ i*2*(RADIUS+1)+(RADIUS+1), RADIUS, 0, 2*Math.PI );
170                 cxt.closePath();
171 
172                 cxt.fill();
173             }
174 }
原文地址:https://www.cnblogs.com/jhmydear/p/3988755.html