案例来自慕课网
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>绚丽的倒计时效果</title> <script src="js/countdown.js" type="text/javascript" charset="utf-8"></script> <script src="js/digit.js" type="text/javascript" charset="utf-8"></script> </head> <body> <center> <canvas id="canvas" ></canvas> </center> </body> </html> var WINDOW_WIDTH = 1024; var WINDOW_HEIGHT = 608; var MARGIN_TOP = 60; var MARGIN_LEFT = 30; var RADIUS = 8; const endTime = new Date(2016, 7, 14, 13, 23, 45); 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 context = canvas.getContext("2d"); canvas.width = WINDOW_WIDTH; canvas.height = WINDOW_HEIGHT; curShowTimeSeconds = getCurrentShowTimeSeconds(); setInterval(function() { render(context); update(); }, 50); } function getCurrentShowTimeSeconds() { var curTime = new Date(); var ret = endTime.getTime() - curTime.getTime(); ret = Math.round(ret / 1000); //毫秒转化为秒数,转化成整数 return ret >= 0 ? ret : 0; //如果ret大于等于0,则返回ret,否则返回0 } //负责数据的绘制 function render(cxt) { cxt.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); //对矩形控件内的函数进行刷新操作 var hours = parseInt(curShowTimeSeconds / 3600); var minutes = parseInt((curShowTimeSeconds - hours * 3600) / 60); var seconds = curShowTimeSeconds % 60; renderDigit(MARGIN_LEFT, MARGIN_TOP, parseInt(hours / 10), cxt); renderDigit(MARGIN_LEFT + 15 * (RADIUS + 1), MARGIN_TOP, parseInt(hours % 10), cxt); renderDigit(MARGIN_LEFT + 30 * (RADIUS + 1), MARGIN_TOP, 10, cxt) renderDigit(MARGIN_LEFT + 39 * (RADIUS + 1), MARGIN_TOP, parseInt(minutes / 10), cxt); renderDigit(MARGIN_LEFT + 54 * (RADIUS + 1), MARGIN_TOP, parseInt(minutes % 10), cxt); renderDigit(MARGIN_LEFT + 69 * (RADIUS + 1), MARGIN_TOP, 10, cxt) renderDigit(MARGIN_LEFT + 78 * (RADIUS + 1), MARGIN_TOP, parseInt(seconds / 10), cxt); renderDigit(MARGIN_LEFT + 93 * (RADIUS + 1), MARGIN_TOP, parseInt(seconds % 10), cxt); for(var i = 0; i < balls.length; i++) { cxt.fillStyle = balls[i].color; cxt.beginPath(); cxt.arc(balls[i].x, balls[i].y, RADIUS, 0, 2 * Math.PI, true); cxt.closePath(); cxt.fill(); } } function renderDigit(x, y, num, cxt) { cxt.fillStyle = "rgb(0,102,153)"; 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) { cxt.beginPath(); cxt.arc(x + j * 2 * (RADIUS + 1) + (RADIUS + 1), y + i * 2 * (RADIUS + 1) + (RADIUS + 1), RADIUS, 0, 2 * Math.PI); cxt.closePath(); cxt.fill(); } } //负责数据的改变 function update() { var nextShowTimeSeconds = getCurrentShowTimeSeconds(); var nextHours = parseInt(nextShowTimeSeconds / 3600); var nextMinutes = parseInt((nextShowTimeSeconds - nextHours * 3600) / 60); var nextSeconds = nextShowTimeSeconds % 60; var curHours = parseInt(curShowTimeSeconds / 3600); var curMinutes = parseInt((curShowTimeSeconds - curHours * 3600) / 60); var curSeconds = curShowTimeSeconds % 60; if(nextSeconds != curSeconds) { if(parseInt(curHours / 10) != parseInt(nextHours / 10)) { addBalls(MARGIN_LEFT + 10, MARGIN_TOP, parseInt(curHours / 10)); } if(parseInt(curHours % 10) != parseInt(nextHours % 10)) { addBalls(MARGIN_LEFT + 15 * (RADIUS + 1), MARGIN_TOP, parseInt(curHours % 10)); } if(parseInt(curMinutes / 10) != parseInt(nextMinutes / 10)) { addBalls(MARGIN_LEFT + 39 * (RADIUS + 1), MARGIN_TOP, parseInt(curMinutes / 10)); } if(parseInt(curMinutes % 10) != parseInt(nextMinutes % 10)) { addBalls(MARGIN_LEFT + 54 * (RADIUS + 1), MARGIN_TOP, parseInt(curMinutes % 10)); } if(parseInt(curSeconds / 10) != parseInt(nextSeconds / 10)) { addBalls(MARGIN_LEFT + 78 * (RADIUS + 1), MARGIN_TOP, parseInt(curSeconds / 10)); } if(parseInt(curSeconds % 10) != parseInt(nextSeconds % 10)) { addBalls(MARGIN_LEFT + 93 * (RADIUS + 1), MARGIN_TOP, parseInt(nextSeconds % 10)); } curShowTimeSeconds = nextShowTimeSeconds; } 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.75; } } //这是一段奇怪效果的代码,不解 // 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(); // } 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 > Math.min(300, 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) } } } 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] ]//: ];