先啥也不说:来张效果图
我是根据:http://www.imooc.com/learn/133 这里的课程进行学习的。大大的感谢liuyubobobo老师的深入浅出的讲解!!
我在这里仅仅提供我自己的代码和整体思路。
我的思路:
1 我们需要创建一个名为Ball的构造函数,每一个小球都是该构造函数的实例。
每个小球都有以下属性:
x坐标,y坐标(本例中,以画布的左上角为原点),颜色,半径,x方向的速度,y方向的速度,y方向的重力加速度
方法:
更新自身属性。(就是根据自己的速度 加速度 判断出下一时刻自身的位置参数以及速度,并改变自身属性)
2 我们需要构造一个函数,这个函数能将根据小球的属性将小球在画布上表现出来;
3 我们需要构造一个定时器,每隔50ms(当然也不用非得是50ms)将画布上的当前小球清空,并重新生成小球并表现出来
通过观察效果图,我们可以看到,效果图中的小球可以分为两类:
第一类是表示(组成)时间的小球,这类小球生命周期只有定时器的运行间隔时间那么长。
第二类是处于掉落状态的小球,这类小球的生命周期比第一类要长,当这类小球滚出了画布,他的生命周记就结束了。
第二类小球需要储存在一个单独的数组中,我们需要一个函数,这个函数能判断小球是否离开了画布,并将离开画布的小球对象从数组中删除
digit.js文件 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>

浙公网安备 33010602011771号