先啥也不說:來張效果圖javascript
我是根據:http://www.imooc.com/learn/133 這裏的課程進行學習的。大大的感謝liuyubobobo老師的深刻淺出的講解!!html
我在這裏僅僅提供我本身的代碼和總體思路。java
個人思路:git
1 咱們須要建立一個名爲Ball的構造函數,每個小球都是該構造函數的實例。canvas
每一個小球都有如下屬性:數組
x座標,y座標(本例中,以畫布的左上角爲原點),顏色,半徑,x方向的速度,y方向的速度,y方向的重力加速度dom
方法:函數
更新自身屬性。(就是根據本身的速度 加速度 判斷出下一時刻自身的位置參數以及速度,並改變自身屬性)學習
2 咱們須要構造一個函數,這個函數能將根據小球的屬性將小球在畫布上表現出來;this
3 咱們須要構造一個定時器,每隔50ms(固然也不用非得是50ms)將畫布上的當前小球清空,並從新生成小球並表現出來
經過觀察效果圖,咱們能夠看到,效果圖中的小球能夠分爲兩類:
第一類是表示(組成)時間的小球,這類小球生命週期只有定時器的運行間隔時間那麼長。
第二類是處於掉落狀態的小球,這類小球的生命週期比第一類要長,當這類小球滾出了畫布,他的生命週記就結束了。
第二類小球須要儲存在一個單獨的數組中,咱們須要一個函數,這個函數能判斷小球是否離開了畫布,並將離開畫布的小球對象從數組中刪除
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <script type='text/javascript'src="digit.js"></script> 7 <style> 8 body{ 9 margin: 0; 10 padding: 0; 11 } 12 canvas{ 13 display: block; 14 margin: 10px auto; 15 border: 1px solid blanchedalmond; 16 } 17 </style> 18 </head> 19 <body> 20 <canvas id="canvas" width="1200" height="650"></canvas> 21 <script type="text/javascript" src="digit.js"></script> 22 <script> 23 var WINDOW_WIDTH = 1200; 24 var WINDOW_HEIGHT = 650; 25 var RADIUS = 8; 26 var MARGIN_TOP = 60; 27 var MARGIN_LEFT = 80; 28 var FLASHTIME = 50; 29 var canvas = document.getElementById('canvas'); 30 var context = canvas.getContext('2d'); 31 var curTimeList = 0; 32 var nextTimeList = 0; 33 // 掉落小球對象數組 34 var fallBallsList = []; 35 window.onload = function(){ 36 var timer = setInterval(function(){ 37 render(context,MARGIN_LEFT,MARGIN_TOP,FLASHTIME); 38 updateFallBalls(RADIUS); 39 console.log(fallBallsList.length) 40 },FLASHTIME) 41 42 43 }; 44 45 function Ball(){ 46 //定義小球對象 47 Ball.prototype.x = 0; // 小球x座標 48 Ball.prototype.y = 0; // 小球y座標 49 Ball.prototype.r = 8; // 小球半徑 50 Ball.prototype.color = 'blue'; // 小球顏色 51 Ball.prototype.vx = 0; // 小球x方向的速度 52 Ball.prototype.vy = 0; // 小球y方向的速度 53 Ball.prototype.g = 0; // 小球的y方向的加速度 54 Ball.prototype.update = function(){ // 更新小球座標以及小球的y方向的速度 55 this.x += this.vx; 56 this.y += this.vy; 57 this.vy += this.g; 58 } 59 } 60 61 function render(context,x0,y0,flashtime){ 62 /* 本函數的做用:在畫布上渲染小球 63 * context: 畫布對象 64 * x0: 整個時間相對於畫布左邊緣的偏移 65 * y0: 整個時間相對於畫布上邊緣的偏移 66 * flashtime: 刷新時間 67 */ 68 // 清空畫布 69 context.clearRect(0,0,1200,650); 70 // 獲取當前時間。並格式化。 若是是12:34:56 則輸出[1,2,10,3,4,10,5,6] 71 curTimeList = getDigitNumList(getTimeStr()); 72 // 獲取下一次定時器運行時刻的時間,並格式化 73 nextTimeList = getDigitNumList(getTimeStr(FLASHTIME)); 74 // 獲取全部的小球對象的數組,包含表示時間的小球以及掉落小球。格式:[ball1,ball2,……,balln] 75 var allballsList = getBallsList(digit,x0,y0); 76 // 全部的小球對象數組,包含了表示時間的小球對象以及掉落小球對象 77 78 for (var i in allballsList){ 79 context.beginPath(); 80 context.arc(allballsList[i].x,allballsList[i].y,allballsList[i].r,0,2*Math.PI); 81 context.closePath(); 82 context.fillStyle = allballsList[i].color; 83 context.fill(); 84 allballsList[i].update() 85 86 } 87 88 } 89 90 function updateFallBalls(r){ 91 // 更新掉落小球對象數組,也就是使那些掉落到畫布下邊緣的小球能反彈上去 並 使離開畫布的小球對象從數組中被刪除, 92 for(var n in fallBallsList){ 93 if(fallBallsList[n].y >= WINDOW_HEIGHT -r){ 94 fallBallsList[n].y = WINDOW_HEIGHT - r; 95 fallBallsList[n].vy = fallBallsList[n].vy * -0.8 96 } 97 } 98 99 var cnt = 0; 100 for (var i in fallBallsList){ 101 if (fallBallsList[i].x + r > 0 && fallBallsList[i].x - r < WINDOW_WIDTH){ 102 fallBallsList[cnt++] = fallBallsList[i]; 103 } 104 } 105 fallBallsList.splice(cnt-1); 106 107 } 108 109 function getBallsList(digit,x0,y0){ 110 // 本函數的做用: 返回全部小球對象組成的數組 111 if(curTimeList != nextTimeList){ 112 for (var n in nextTimeList){ 113 if(nextTimeList[n] != curTimeList[n]){ 114 // 更新掉落小球對象組成的數組 115 fallBallsList = fallBallsList.concat(_GetOneDigitBallsList(digit[curTimeList[n]],n,x0,y0,RADIUS,true)); 116 117 } 118 } 119 } 120 var ballsList = []; 121 // 生成表示時間的小球對象組成的數組 122 for(var i in curTimeList){ 123 ballsList = ballsList.concat(_GetOneDigitBallsList(digit[curTimeList[i]],i,x0,y0,RADIUS)); 124 } 125 126 return ballsList.concat(fallBallsList) 127 } 128 129 130 131 function _GetOneDigitBallsList(list,position,leftOffset,topOffset,r,choice){ 132 /* 本函數的做用是:獲取組成一個數字的小球對象數組。 133 * list: 數組digit的某一項 134 * position: 該數字在時間中的位置 135 * r: 小球的半徑 136 * choice:若爲true,則隨機小球對象的顏色,速度以及加速度,也就是說,若爲true生成的小球對象爲掉落小球 137 * 當時間是21:43:65秒時,若是咱們想要獲得組成數字3的小球列表, 138 * 應該這樣調用本函數:_GetOneDigitBallsList(digit[3],4,左偏移,右偏移,r) 139 * 140 */ 141 var ballsList = []; 142 var x0 = 0; 143 var y0 = 0; 144 for(var i in list){ 145 y0 = topOffset + i*2*(r+1)+r+1; 146 for (var j in list[i]){ 147 if(list[i][j] == 1){ 148 if(position < 3){ 149 x0 = leftOffset + position * 14 * (r+1)+ (r+1) *position + r+1 +j * 18 150 }else if(position < 6){ 151 x0 = leftOffset + (position -1) *14*(r+1)+(r+1)*position + 8* (r+1) +r +1 +j * 18 152 }else { 153 x0 = leftOffset + (position-2)*14*(r+1)+ (r+1)*position + 16*(r+1) + r +1 +j * 18 154 } 155 ballsList.push(getOneBall(x0,y0,r,choice)) 156 } 157 } 158 } 159 return ballsList 160 } 161 162 function getOneBall(x,y,r,random){ 163 /* 164 * 返回一個小球對象 165 * x: 小球圓心的x座標 166 * y: 小球圓心的y座標 167 * r: 小球的半徑 168 * random: 是否隨機小球的速度,顏色以及加速度 169 */ 170 var ball = new Ball(); 171 ball.x = x; 172 ball.y = y; 173 ball.r = r; 174 if(random){ 175 ball.color = randomColor(); 176 ball.vx = randomV(); 177 ball.vy = randomV(); 178 ball.g = 1.5 + Math.random(); 179 } 180 181 return ball 182 } 183 184 function getDigitNumList(timeStr){ 185 /* 返回當前時間字符所對應的digit項數組 186 * 字符0-9分別對應着 digit 數組中的0-9索引項,而字符 ‘:’ 則對應着digit[10] 187 */ 188 var digitList = []; 189 for (var i in timeStr){ 190 if (timeStr[i] == ':'){ 191 var num = 10; 192 }else{ 193 var num = parseInt(timeStr[i]); 194 } 195 digitList.push(num); 196 } 197 return digitList; 198 } 199 200 function getTimeStr(offset){ 201 var time = new Date(); 202 if(offset){ 203 time = new Date(time.getTime()+offset) 204 } 205 var hours = time.getHours()>9?time.getHours():'0'+time.getHours(); 206 var mins = time.getMinutes()>9?time.getMinutes():'0'+time.getMinutes(); 207 var seconds = time.getSeconds()>9?time.getSeconds():'0'+time.getSeconds(); 208 return hours + ':' + mins +':' + seconds; 209 } 210 211 function randomColor(){ 212 var colorList = ["#33B5E5", "#0099CC", "#AA66CC", "#9933CC", "#99CC00", "#669900", "#FFBB33", "#FF8800", "#FF4444", "#CC0000"]; 213 return colorList[Math.floor(Math.random()*colorList.length)] 214 } 215 216 function randomV(){ 217 return Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4 218 } 219 220 221 222 223 </script> 224 </body> 225 </html>