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 }