想要在自己做的网页中,加入canvas动画效果,但是发现模板各种调整不好,觉得还是要对canvas有所了解,才可以让自己的网页变得狂拽炫酷吊炸天!
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <canvas id="canvas" style="border:1px solid #aaa;display: block;margin: 50px auto;">
9 </canvas>
10
11 <script>
12 window.onload=function (ev) {
13 var canvas=document.getElementById('canvas');
14 //画布的长宽,没有单位的
15 canvas.width=1024;
16 canvas.height=600;
17 var context=canvas.getContext('2d');
18 //使用context绘制,画图之前的配置
19
20
21 //1.绘制折线图形
22 context.beginPath();
23 context.moveTo(100,100);
24 context.lineTo(500,500);
25 context.lineTo(100,500);
26 context.lineTo(100,100);
27 context.closePath();
28 //图线的状态,如果用context.beginPath();.... context.closePath();包住,才只对下面最近的一个 context.stroke();(画线)命令起作用,不然就对所有 context.stroke();起作用
29
30 context.lineWidth=5;//画线的粗细
31 context.strokeStyle='#005588';
32 context.stroke();
33
34 context.beginPath();
35 context.moveTo(200,100);
36 context.lineTo(600,500);
37 context.closePath();
38
39 context.strokeStyle='black'; //画线的颜色
40 context.stroke();
41
42
43 }
44 </script>
45 </body>
46 </html>
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <canvas id="canvas" style="border:1px solid #aaa;display: block;margin: 50px auto;">
9 </canvas>
10
11 <script>
12 window.onload=function (ev) {
13 var canvas=document.getElementById('canvas');
14 canvas.width=1024;
15 canvas.height=600;
16 var context=canvas.getContext('2d');
17 //使用context绘制
18
19 context.lineWidth=5;
20 context.strokeStyle="#005588";
21
22 for(var i=0;i<10;i++){
23 context.beginPath();
24 context.arc(50+i*100,60,40,0,2*Math.PI*(i+1)/10);
25 context.closePath();
26
27 context.stroke()
28 }
29
30 for(var i=0;i<10;i++){
31 context.beginPath();
32 context.arc(50+i*100,180,40,0,2*Math.PI*(i+1)/10);
33 // context.closePath();
34
35 context.stroke()
36 }
37
38
39 for(var i=0;i<10;i++){
40 context.beginPath();
41 context.arc(50+i*100,300,40,0,2*Math.PI*(i+1)/10,true);
42 context.closePath();
43
44 context.stroke()
45 }
46
47 for(var i=0;i<10;i++){
48 context.beginPath();
49 context.arc(50+i*100,420,40,0,2*Math.PI*(i+1)/10,true);
50 // context.closePath();
51
52 context.stroke()
53 }
54
55 context.fillStyle="#005588";
56 for(var i=0;i<10;i++){
57 context.beginPath();
58 context.arc(50+i*100,540,40,0,2*Math.PI*(i+1)/10);
59 context.closePath();
60
61 context.fill()
62 }
63
64 }
65 </script>
66 </body>
67 </html>
新建两个js文件:digit.js 存放一个三维数组,countdown.js实现时钟效果
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <canvas id="canvas" style="border:1px solid #aaa;display: block;margin: 50px auto;">
9 </canvas>
10
11 <script src="digit.js"></script>
12 <script src="countdown.js"></script>
13
14 </body>
15 </html>
1 digit =
2 [
3 [
4 [0,0,1,1,1,0,0],
5 [0,1,1,0,1,1,0],
6 [1,1,0,0,0,1,1],
7 [1,1,0,0,0,1,1],
8 [1,1,0,0,0,1,1],
9 [1,1,0,0,0,1,1],
10 [1,1,0,0,0,1,1],
11 [1,1,0,0,0,1,1],
12 [0,1,1,0,1,1,0],
13 [0,0,1,1,1,0,0]
14 ],//0
15 [
16 [0,0,0,1,1,0,0],
17 [0,1,1,1,1,0,0],
18 [0,0,0,1,1,0,0],
19 [0,0,0,1,1,0,0],
20 [0,0,0,1,1,0,0],
21 [0,0,0,1,1,0,0],
22 [0,0,0,1,1,0,0],
23 [0,0,0,1,1,0,0],
24 [0,0,0,1,1,0,0],
25 [1,1,1,1,1,1,1]
26 ],//1
27 [
28 [0,1,1,1,1,1,0],
29 [1,1,0,0,0,1,1],
30 [0,0,0,0,0,1,1],
31 [0,0,0,0,1,1,0],
32 [0,0,0,1,1,0,0],
33 [0,0,1,1,0,0,0],
34 [0,1,1,0,0,0,0],
35 [1,1,0,0,0,0,0],
36 [1,1,0,0,0,1,1],
37 [1,1,1,1,1,1,1]
38 ],//2
39 [
40 [1,1,1,1,1,1,1],
41 [0,0,0,0,0,1,1],
42 [0,0,0,0,1,1,0],
43 [0,0,0,1,1,0,0],
44 [0,0,1,1,1,0,0],
45 [0,0,0,0,1,1,0],
46 [0,0,0,0,0,1,1],
47 [0,0,0,0,0,1,1],
48 [1,1,0,0,0,1,1],
49 [0,1,1,1,1,1,0]
50 ],//3
51 [
52 [0,0,0,0,1,1,0],
53 [0,0,0,1,1,1,0],
54 [0,0,1,1,1,1,0],
55 [0,1,1,0,1,1,0],
56 [1,1,0,0,1,1,0],
57 [1,1,1,1,1,1,1],
58 [0,0,0,0,1,1,0],
59 [0,0,0,0,1,1,0],
60 [0,0,0,0,1,1,0],
61 [0,0,0,1,1,1,1]
62 ],//4
63 [
64 [1,1,1,1,1,1,1],
65 [1,1,0,0,0,0,0],
66 [1,1,0,0,0,0,0],
67 [1,1,1,1,1,1,0],
68 [0,0,0,0,0,1,1],
69 [0,0,0,0,0,1,1],
70 [0,0,0,0,0,1,1],
71 [0,0,0,0,0,1,1],
72 [1,1,0,0,0,1,1],
73 [0,1,1,1,1,1,0]
74 ],//5
75 [
76 [0,0,0,0,1,1,0],
77 [0,0,1,1,0,0,0],
78 [0,1,1,0,0,0,0],
79 [1,1,0,0,0,0,0],
80 [1,1,0,1,1,1,0],
81 [1,1,0,0,0,1,1],
82 [1,1,0,0,0,1,1],
83 [1,1,0,0,0,1,1],
84 [1,1,0,0,0,1,1],
85 [0,1,1,1,1,1,0]
86 ],//6
87 [
88 [1,1,1,1,1,1,1],
89 [1,1,0,0,0,1,1],
90 [0,0,0,0,1,1,0],
91 [0,0,0,0,1,1,0],
92 [0,0,0,1,1,0,0],
93 [0,0,0,1,1,0,0],
94 [0,0,1,1,0,0,0],
95 [0,0,1,1,0,0,0],
96 [0,0,1,1,0,0,0],
97 [0,0,1,1,0,0,0]
98 ],//7
99 [
100 [0,1,1,1,1,1,0],
101 [1,1,0,0,0,1,1],
102 [1,1,0,0,0,1,1],
103 [1,1,0,0,0,1,1],
104 [0,1,1,1,1,1,0],
105 [1,1,0,0,0,1,1],
106 [1,1,0,0,0,1,1],
107 [1,1,0,0,0,1,1],
108 [1,1,0,0,0,1,1],
109 [0,1,1,1,1,1,0]
110 ],//8
111 [
112 [0,1,1,1,1,1,0],
113 [1,1,0,0,0,1,1],
114 [1,1,0,0,0,1,1],
115 [1,1,0,0,0,1,1],
116 [0,1,1,1,0,1,1],
117 [0,0,0,0,0,1,1],
118 [0,0,0,0,0,1,1],
119 [0,0,0,0,1,1,0],
120 [0,0,0,1,1,0,0],
121 [0,1,1,0,0,0,0]
122 ],//9
123 [
124 [0,0,0,0],
125 [0,0,0,0],
126 [0,1,1,0],
127 [0,1,1,0],
128 [0,0,0,0],
129 [0,0,0,0],
130 [0,1,1,0],
131 [0,1,1,0],
132 [0,0,0,0],
133 [0,0,0,0]
134 ]//:
135 ];
1 var WINDOW_WIDTH=1024;
2 var WINDOW_HEIGHT=600;
3 var RADIUS=8;
4 var MARGIN_TOP=60;
5 var MARGIN_LIFT=30;
6 const endTime=new Date("2018/3/20,18:47:52");//js中的月份是从0-11,如果要表示7月,则用6表示,const代表常量
7 var curShowTimeSeconds=0;
8
9
10 window.onload=function () {
11
12 var canvas=document.getElementById('canvas');
13 var context=canvas.getContext('2d');
14
15 canvas.width=WINDOW_WIDTH;
16 canvas.height=WINDOW_HEIGHT;
17
18 curShowTimeSeconds=getCurrentShowTimeSeconds();
19 render(context);
20 };
21
22 function getCurrentShowTimeSeconds() {
23 var curTime=new Date();
24 var ret=endTime.getTime()-curTime.getTime();
25 ret=Math.round(ret/1000);
26 return ret>=0?ret:0;
27 }
28
29
30 function render(cxt) {
31 var hours=parseInt(curShowTimeSeconds/3600);
32 var minutes=parseInt((curShowTimeSeconds-hours * 3600)/60);
33 var seconds=curShowTimeSeconds%60;
34
35 renderDigit(MARGIN_LIFT,MARGIN_TOP,parseInt(hours/10),cxt);
36 renderDigit(MARGIN_LIFT+15*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),cxt);
37 renderDigit(MARGIN_LIFT+30*(RADIUS+1),MARGIN_TOP,10,cxt);
38 renderDigit(MARGIN_LIFT+39*(RADIUS+1),MARGIN_TOP,parseInt(minutes/10),cxt);
39 renderDigit(MARGIN_LIFT+54*(RADIUS+1),MARGIN_TOP,parseInt(minutes%10),cxt);
40 renderDigit(MARGIN_LIFT+69*(RADIUS+1),MARGIN_TOP,parseInt(10),cxt);
41 renderDigit(MARGIN_LIFT+78*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10),cxt);
42 renderDigit(MARGIN_LIFT+93*(RADIUS+1),MARGIN_TOP,parseInt(seconds%10),cxt);
43
44 }
45
46 function renderDigit(x,y,num,cxt) {
47 cxt.fillStyle="rgb(0,102,153)";
48
49 for(var i=0;i<digit[num].length;i++)
50 for(var j=0;j<digit[num][i].length;j++)
51 if(digit[num][i][j]==1){
52 cxt.beginPath();
53 cxt.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI);
54 cxt.closePath();
55
56 cxt.fill()
57 }
58 }
注意:数组阵列中,只能从0-9,如果超过10,就会报错,换言之,定义的到期时间距离程序当前时间不能超过100个小时,也就是四天。
1 var WINDOW_WIDTH=1024;
2 var WINDOW_HEIGHT=600;
3 var RADIUS=8;
4 var MARGIN_TOP=60;
5 var MARGIN_LIFT=30;
6 const endTime=new Date("2018/3/20,18:47:52");//js中的月份是从0-11,如果要表示7月,则用6表示,const代表常量
7 var curShowTimeSeconds=0;
8
9
10 window.onload=function () {
11
12 var canvas=document.getElementById('canvas');
13 var context=canvas.getContext('2d');
14
15 canvas.width=WINDOW_WIDTH;
16 canvas.height=WINDOW_HEIGHT;
17
18 curShowTimeSeconds=getCurrentShowTimeSeconds();
19 // render(context);
20 setInterval(function () {
21 render(context);
22 updata();
23
24 },
25 50)
26 };
27
28 function updata() {
29 var nextShowTimeSeconds=getCurrentShowTimeSeconds();
30
31 var nextHours=parseInt(nextShowTimeSeconds/3600);
32 var nextMinutes=parseInt((nextShowTimeSeconds-nextHours*3600)/60);
33 var nextSeconds=nextShowTimeSeconds%60;
34
35 var curHours=parseInt(curShowTimeSeconds/3600);
36 var curMinutes=parseInt((curShowTimeSeconds-curHours * 3600)/60);
37 var curSeconds=curShowTimeSeconds%60;
38
39 if(nextSeconds!=curSeconds){
40 curShowTimeSeconds=nextShowTimeSeconds;
41 }
42
43
44 }
45
46 function getCurrentShowTimeSeconds() {
47 var curTime=new Date();
48 var ret=endTime.getTime()-curTime.getTime();
49 ret=Math.round(ret/1000);
50 return ret>=0?ret:0;
51 }
52
53 function render(cxt) {
54
55 cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);//对整个画布进行刷新,防止新画的跟以前画的叠加
56 var hours=parseInt(curShowTimeSeconds/3600);
57 var minutes=parseInt((curShowTimeSeconds-hours * 3600)/60);
58 var seconds=curShowTimeSeconds%60;
59
60 renderDigit(MARGIN_LIFT,MARGIN_TOP,parseInt(hours/10),cxt);
61 renderDigit(MARGIN_LIFT+15*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),cxt);
62 renderDigit(MARGIN_LIFT+30*(RADIUS+1),MARGIN_TOP,10,cxt);
63 renderDigit(MARGIN_LIFT+39*(RADIUS+1),MARGIN_TOP,parseInt(minutes/10),cxt);
64 renderDigit(MARGIN_LIFT+54*(RADIUS+1),MARGIN_TOP,parseInt(minutes%10),cxt);
65 renderDigit(MARGIN_LIFT+69*(RADIUS+1),MARGIN_TOP,parseInt(10),cxt);
66 renderDigit(MARGIN_LIFT+78*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10),cxt);
67 renderDigit(MARGIN_LIFT+93*(RADIUS+1),MARGIN_TOP,parseInt(seconds%10),cxt);
68
69 }
70
71 function renderDigit(x,y,num,cxt) {
72 cxt.fillStyle="rgb(0,102,153)";
73
74 for(var i=0;i<digit[num].length;i++)
75 for(var j=0;j<digit[num][i].length;j++)
76 if(digit[num][i][j]==1){
77 cxt.beginPath();
78 cxt.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI);
79 cxt.closePath();
80
81 cxt.fill()
82 }
83 }
各一秒变化一次:
新建一个physical.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Title</title>
6 </head>
7 <body>
8 <canvas id="canvas" style="border:1px solid #aaa;display: block;margin: 50px auto;"></canvas>
9 </body>
10
11 <script>
12 var ball={x:512,y:100,r:20,g:2,vx:-4,vy:0,color:"#005588"};
13 window.onload=function (ev) {
14 var canvas=document.getElementById("canvas");
15 canvas.width=1024;
16 canvas.height=600;
17 var context=canvas.getContext("2d");
18 //每隔50毫秒,生成一次小球,并更新下一次小球出现的位置和速度
19 setInterval(function () {
20 render(context);
21 update();
22 },50)
23 };
24 function render(cxt) {
25 cxt.clearRect(0,0,cxt.canvas.width,cxt.canvas.height);
26
27 cxt.fillStyle=ball.color;
28 cxt.beginPath();
29 cxt.arc(ball.x,ball.y,ball.r,0,2*Math.PI)
30 cxt.closePath();
31
32 cxt.fill();
33 }
34 function update() {
35 ball.x+=ball.vx;
36 ball.y+=ball.vy;
37 ball.vy+=ball.g;
38 if(ball.y>canvas.height-ball.r){
39 ball.y=canvas.height-ball.r;
40 ball.vy=-ball.vy*0.5;
41 }
42 }
43
44 </script>
45 </html>
1.声明一个数组存放所有产生的小球,声明另一个数组存放几种颜色,用于随机取出赋给小球,以达到多种颜色小球的效果:
1 //小球
2 var balls = [];
3 const colors = ["#33B5E5",
4 "#0099CC",
5 "#AA66CC",
6 "#9933CC",
7 "#99CC00",
8 "#669900",
9 "#FFBB33",
10 "#FF8800",
11 "#FF4444",
12 "#CC0000"]
2.在update()函数中增加判断生成物理小球的条件,以及调用更新小球所在位置和速度的函数updateBalls():
1 if(nextSeconds!=curSeconds){
2 //小球
3 if( parseInt(curHours/10) != parseInt(nextHours/10) ){
4 addBalls( MARGIN_LIFT + 0 , MARGIN_TOP , parseInt(curHours/10) );
5 }
6 if( parseInt(curHours%10) != parseInt(nextHours%10) ){
7 addBalls( MARGIN_LIFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(curHours/10) );
8 }
9
10 if( parseInt(curMinutes/10) != parseInt(nextMinutes/10) ){
11 addBalls( MARGIN_LIFT + 39*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes/10) );
12 }
13 if( parseInt(curMinutes%10) != parseInt(nextMinutes%10) ){
14 addBalls( MARGIN_LIFT + 54*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes%10) );
15 }
16
17 if( parseInt(curSeconds/10) != parseInt(nextSeconds/10) ){
18 addBalls( MARGIN_LIFT + 78*(RADIUS+1) , MARGIN_TOP , parseInt(curSeconds/10) );
19 }
20 if( parseInt(curSeconds%10) != parseInt(nextSeconds%10) ){
21 addBalls( MARGIN_LIFT + 93*(RADIUS+1) , MARGIN_TOP , parseInt(nextSeconds%10) );
22 }
23
24 //更新时间
25 curShowTimeSeconds=nextShowTimeSeconds;
26 }
27 //更新小球的速度
28 updateBalls();
3.定义设置要生成的小球的各种参数的函数addBalls():
1 function addBalls( x , y , num ){
2 console.log("addBalls");
3 for( var i=0;i<digit[num].length;i++)
4 for(var j=0;j<digit[num][i].length;j++)
5 if( digit[num][i][j] == 1 ){
6 var aBall = {
7 x:x+j*2*(RADIUS+1)+(RADIUS+1),
8 y:y+i*2*(RADIUS+1)+(RADIUS+1),
9 g:1.5+Math.random(),
10 vx:Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4,
11 vy:-5,
12 color: colors[ Math.floor( Math.random()*colors.length ) ]
13 };
14 balls.push(aBall);
15 }
16 }
4.定义更新小球位置和速度的函数updateBalls():
1 function updateBalls(){
2 for( var i = 0 ; i < balls.length ; i ++ ){
3 balls[i].x += balls[i].vx;
4 balls[i].y += balls[i].vy;
5 balls[i].vy += balls[i].g;
6 if( balls[i].y >= WINDOW_HEIGHT-RADIUS ){
7 balls[i].y = WINDOW_HEIGHT-RADIUS;
8 balls[i].vy = - balls[i].vy*0.75;
9 }
10 }
11 }
5.在render函数中增加画物理小球的代码:
1 for(var i=0;i<balls.length;i++){
2 cxt.fillStyle=balls[i].color;
3
4 cxt.beginPath();
5 cxt.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true);
6 cxt.closePath();
7
8 cxt.fill();
9 }
修改后的countdown.js为:
1 var WINDOW_WIDTH=1024;
2 var WINDOW_HEIGHT=600;
3 var RADIUS=8;
4 var MARGIN_TOP=60;
5 var MARGIN_LIFT=30;
6 const endTime=new Date("2018/3/20,18:47:52");//const代表常量
7 var curShowTimeSeconds=0;
8
9 //小球
10 var balls = [];
11 const colors = ["#33B5E5",
12 "#0099CC",
13 "#AA66CC",
14 "#9933CC",
15 "#99CC00",
16 "#669900",
17 "#FFBB33",
18 "#FF8800",
19 "#FF4444",
20 "#CC0000"]
21
22 window.onload=function () {
23
24 var canvas=document.getElementById('canvas');
25 var context=canvas.getContext('2d');
26
27 canvas.width=WINDOW_WIDTH;
28 canvas.height=WINDOW_HEIGHT;
29
30 curShowTimeSeconds=getCurrentShowTimeSeconds();
31 // render(context);
32 setInterval(function () {
33 render(context);
34 update();
35 },
36 50)
37 };
38
39 function update() {
40 var nextShowTimeSeconds=getCurrentShowTimeSeconds();
41
42 var nextHours=parseInt(nextShowTimeSeconds/3600);
43 var nextMinutes=parseInt((nextShowTimeSeconds-nextHours*3600)/60);
44 var nextSeconds=nextShowTimeSeconds%60;
45
46 var curHours=parseInt(curShowTimeSeconds/3600);
47 var curMinutes=parseInt((curShowTimeSeconds-curHours * 3600)/60);
48 var curSeconds=curShowTimeSeconds%60;
49
50 if(nextSeconds!=curSeconds){
51 //小球
52 if( parseInt(curHours/10) != parseInt(nextHours/10) ){
53 addBalls( MARGIN_LIFT + 0 , MARGIN_TOP , parseInt(curHours/10) );
54 }
55 if( parseInt(curHours%10) != parseInt(nextHours%10) ){
56 addBalls( MARGIN_LIFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(curHours/10) );
57 }
58
59 if( parseInt(curMinutes/10) != parseInt(nextMinutes/10) ){
60 addBalls( MARGIN_LIFT + 39*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes/10) );
61 }
62 if( parseInt(curMinutes%10) != parseInt(nextMinutes%10) ){
63 addBalls( MARGIN_LIFT + 54*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes%10) );
64 }
65
66 if( parseInt(curSeconds/10) != parseInt(nextSeconds/10) ){
67 addBalls( MARGIN_LIFT + 78*(RADIUS+1) , MARGIN_TOP , parseInt(curSeconds/10) );
68 }
69 if( parseInt(curSeconds%10) != parseInt(nextSeconds%10) ){
70 addBalls( MARGIN_LIFT + 93*(RADIUS+1) , MARGIN_TOP , parseInt(nextSeconds%10) );
71 }
72
73 //更新时间
74 curShowTimeSeconds=nextShowTimeSeconds;
75 }
76 //更新小球的速度
77 updateBalls();
78
79 }
80
81 function updateBalls(){
82 for( var i = 0 ; i < balls.length ; i ++ ){
83 balls[i].x += balls[i].vx;
84 balls[i].y += balls[i].vy;
85 balls[i].vy += balls[i].g;
86 if( balls[i].y >= WINDOW_HEIGHT-RADIUS ){
87 balls[i].y = WINDOW_HEIGHT-RADIUS;
88 balls[i].vy = - balls[i].vy*0.75;
89 }
90 }
91 }
92
93 function addBalls( x , y , num ){
94 console.log("addBalls");
95 for( var i=0;i<digit[num].length;i++)
96 for(var j=0;j<digit[num][i].length;j++)
97 if( digit[num][i][j] == 1 ){
98 var aBall = {
99 x:x+j*2*(RADIUS+1)+(RADIUS+1),
100 y:y+i*2*(RADIUS+1)+(RADIUS+1),
101 g:1.5+Math.random(),
102 vx:Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4,
103 vy:-5,
104 color: colors[ Math.floor( Math.random()*colors.length ) ]
105 };
106 balls.push(aBall);
107 }
108 }
109
110 function getCurrentShowTimeSeconds() {
111 var curTime=new Date();
112 var ret=endTime.getTime()-curTime.getTime();
113 ret=Math.round(ret/1000);
114 return ret>=0?ret:0;
115 }
116
117 function render(cxt) {
118
119 cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);//对整个画布进行刷新,防止新画的跟以前画的叠加
120 var hours=parseInt(curShowTimeSeconds/3600);
121 var minutes=parseInt((curShowTimeSeconds-hours * 3600)/60);
122 var seconds=curShowTimeSeconds%60;
123
124 renderDigit(MARGIN_LIFT,MARGIN_TOP,parseInt(hours/10),cxt);
125 renderDigit(MARGIN_LIFT+15*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),cxt);
126 renderDigit(MARGIN_LIFT+30*(RADIUS+1),MARGIN_TOP,10,cxt);
127 renderDigit(MARGIN_LIFT+39*(RADIUS+1),MARGIN_TOP,parseInt(minutes/10),cxt);
128 renderDigit(MARGIN_LIFT+54*(RADIUS+1),MARGIN_TOP,parseInt(minutes%10),cxt);
129 renderDigit(MARGIN_LIFT+69*(RADIUS+1),MARGIN_TOP,parseInt(10),cxt);
130 renderDigit(MARGIN_LIFT+78*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10),cxt);
131 renderDigit(MARGIN_LIFT+93*(RADIUS+1),MARGIN_TOP,parseInt(seconds%10),cxt);
132
133 for(var i=0;i<balls.length;i++){
134 cxt.fillStyle=balls[i].color;
135
136 cxt.beginPath();
137 cxt.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true);
138 cxt.closePath();
139
140 cxt.fill();
141 }
142
143 }
144
145 function renderDigit(x,y,num,cxt) {
146 cxt.fillStyle="rgb(0,102,153)";
147
148 for(var i=0;i<digit[num].length;i++)
149 for(var j=0;j<digit[num][i].length;j++)
150 if(digit[num][i][j]==1){
151 cxt.beginPath();
152 cxt.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI);
153 cxt.closePath();
154
155 cxt.fill()
156 }
157 }
效果达到了,不过小球会越来越多,最后弄得网页很卡很卡,对于代码的性能优化,是具有必要性的!
改写countdown.js给updateBalls增加代码,让物理小球离开画布的,全都消失解放内存。(原视频教程中bug,我用另外的方法实现的,效果不错)
1 var cnt=[];
2 for(var i=0;i<balls.length;i++){
3 if(balls[i].x-RADIUS>0&&balls[i].x+RADIUS<WINDOW_WIDTH){
4 cnt.push(balls[i]);
5 }
6 }
7 balls=cnt;
修改以后的countdown.js代码:
1 var WINDOW_WIDTH=1024;
2 var WINDOW_HEIGHT=600;
3 var RADIUS=8;
4 var MARGIN_TOP=60;
5 var MARGIN_LIFT=30;
6 const endTime=new Date("2018/3/20,18:47:52");//const代表常量
7 var curShowTimeSeconds=0;
8
9 //小球
10 var balls = [];
11 const colors = ["#33B5E5",
12 "#0099CC",
13 "#AA66CC",
14 "#9933CC",
15 "#99CC00",
16 "#669900",
17 "#FFBB33",
18 "#FF8800",
19 "#FF4444",
20 "#CC0000"]
21
22 window.onload=function () {
23
24 var canvas=document.getElementById('canvas');
25 var context=canvas.getContext('2d');
26
27 canvas.width=WINDOW_WIDTH;
28 canvas.height=WINDOW_HEIGHT;
29
30 curShowTimeSeconds=getCurrentShowTimeSeconds();
31 // render(context);
32 setInterval(function () {
33 render(context);
34 update();
35 //打印物理小球个数
36 console.log(balls.length);
37 },
38 50)
39 };
40
41 function update() {
42 var nextShowTimeSeconds=getCurrentShowTimeSeconds();
43
44 var nextHours=parseInt(nextShowTimeSeconds/3600);
45 var nextMinutes=parseInt((nextShowTimeSeconds-nextHours*3600)/60);
46 var nextSeconds=nextShowTimeSeconds%60;
47
48 var curHours=parseInt(curShowTimeSeconds/3600);
49 var curMinutes=parseInt((curShowTimeSeconds-curHours * 3600)/60);
50 var curSeconds=curShowTimeSeconds%60;
51
52 if(nextSeconds!=curSeconds){
53 //小球
54 if( parseInt(curHours/10) != parseInt(nextHours/10) ){
55 addBalls( MARGIN_LIFT + 0 , MARGIN_TOP , parseInt(curHours/10) );
56 }
57 if( parseInt(curHours%10) != parseInt(nextHours%10) ){
58 addBalls( MARGIN_LIFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(curHours/10) );
59 }
60
61 if( parseInt(curMinutes/10) != parseInt(nextMinutes/10) ){
62 addBalls( MARGIN_LIFT + 39*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes/10) );
63 }
64 if( parseInt(curMinutes%10) != parseInt(nextMinutes%10) ){
65 addBalls( MARGIN_LIFT + 54*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes%10) );
66 }
67
68 if( parseInt(curSeconds/10) != parseInt(nextSeconds/10) ){
69 addBalls( MARGIN_LIFT + 78*(RADIUS+1) , MARGIN_TOP , parseInt(curSeconds/10) );
70 }
71 if( parseInt(curSeconds%10) != parseInt(nextSeconds%10) ){
72 addBalls( MARGIN_LIFT + 93*(RADIUS+1) , MARGIN_TOP , parseInt(nextSeconds%10) );
73 }
74
75 //更新时间
76 curShowTimeSeconds=nextShowTimeSeconds;
77 }
78 //更新小球的速度
79 updateBalls();
80
81 }
82
83 function updateBalls(){
84 for( var i = 0 ; i < balls.length ; i ++ ){
85 balls[i].x += balls[i].vx;
86 balls[i].y += balls[i].vy;
87 balls[i].vy += balls[i].g;
88 if( balls[i].y >= WINDOW_HEIGHT-RADIUS ){
89 balls[i].y = WINDOW_HEIGHT-RADIUS;
90 balls[i].vy = - balls[i].vy*0.75;
91 }
92 }
93
94 var cnt=[];
95 for(var i=0;i<balls.length;i++){
96 if(balls[i].x-RADIUS>0&&balls[i].x+RADIUS<WINDOW_WIDTH){
97 cnt.push(balls[i]);
98 }
99 }
100 balls=cnt;
101
102 }
103
104 function addBalls( x , y , num ){
105 for( var i=0;i<digit[num].length;i++)
106 for(var j=0;j<digit[num][i].length;j++)
107 if( digit[num][i][j] == 1 ){
108 var aBall = {
109 x:x+j*2*(RADIUS+1)+(RADIUS+1),
110 y:y+i*2*(RADIUS+1)+(RADIUS+1),
111 g:1.5+Math.random(),
112 vx:Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4,
113 vy:-5,
114 color: colors[ Math.floor( Math.random()*colors.length ) ]
115 };
116 balls.push(aBall);
117 }
118 }
119
120 function getCurrentShowTimeSeconds() {
121 var curTime=new Date();
122 var ret=endTime.getTime()-curTime.getTime();
123 ret=Math.round(ret/1000);
124 return ret>=0?ret:0;
125 }
126
127 function render(cxt) {
128
129 cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);//对整个画布进行刷新,防止新画的跟以前画的叠加
130 var hours=parseInt(curShowTimeSeconds/3600);
131 var minutes=parseInt((curShowTimeSeconds-hours * 3600)/60);
132 var seconds=curShowTimeSeconds%60;
133
134 renderDigit(MARGIN_LIFT,MARGIN_TOP,parseInt(hours/10),cxt);
135 renderDigit(MARGIN_LIFT+15*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),cxt);
136 renderDigit(MARGIN_LIFT+30*(RADIUS+1),MARGIN_TOP,10,cxt);
137 renderDigit(MARGIN_LIFT+39*(RADIUS+1),MARGIN_TOP,parseInt(minutes/10),cxt);
138 renderDigit(MARGIN_LIFT+54*(RADIUS+1),MARGIN_TOP,parseInt(minutes%10),cxt);
139 renderDigit(MARGIN_LIFT+69*(RADIUS+1),MARGIN_TOP,parseInt(10),cxt);
140 renderDigit(MARGIN_LIFT+78*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10),cxt);
141 renderDigit(MARGIN_LIFT+93*(RADIUS+1),MARGIN_TOP,parseInt(seconds%10),cxt);
142
143 for(var i=0;i<balls.length;i++){
144 cxt.fillStyle=balls[i].color;
145
146 cxt.beginPath();
147 cxt.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true);
148 cxt.closePath();
149
150 cxt.fill();
151 }
152
153 }
154
155 function renderDigit(x,y,num,cxt) {
156 cxt.fillStyle="rgb(0,102,153)";
157
158 for(var i=0;i<digit[num].length;i++)
159 for(var j=0;j<digit[num][i].length;j++)
160 if(digit[num][i][j]==1){
161 cxt.beginPath();
162 cxt.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI);
163 cxt.closePath();
164
165 cxt.fill()
166 }
167 }
效果图:
改写countdown.js中的getCurrentShowTimeSeconds函数:
1 function getCurrentShowTimeSeconds() {
2 var curTime=new Date();
3 var ret=curTime.getHours()*3600+curTime.getMinutes()*60+curTime.getSeconds();
4 return ret;
5 }
countdown.js时钟代码:
1 var WINDOW_WIDTH=1024;
2 var WINDOW_HEIGHT=600;
3 var RADIUS=8;
4 var MARGIN_TOP=60;
5 var MARGIN_LIFT=30;
6 //const endTime=new Date("2018/3/20,18:47:52");//const代表常量
7 var curShowTimeSeconds=0;
8
9 //小球
10 var balls = [];
11 const colors = ["#33B5E5",
12 "#0099CC",
13 "#AA66CC",
14 "#9933CC",
15 "#99CC00",
16 "#669900",
17 "#FFBB33",
18 "#FF8800",
19 "#FF4444",
20 "#CC0000"]
21
22 window.onload=function () {
23
24 var canvas=document.getElementById('canvas');
25 var context=canvas.getContext('2d');
26
27 canvas.width=WINDOW_WIDTH;
28 canvas.height=WINDOW_HEIGHT;
29
30 curShowTimeSeconds=getCurrentShowTimeSeconds();
31 // render(context);
32 setInterval(function () {
33 render(context);
34 update();
35 //打印物理小球个数
36 console.log(balls.length);
37 },
38 50)
39 };
40
41 function update() {
42 var nextShowTimeSeconds=getCurrentShowTimeSeconds();
43
44 var nextHours=parseInt(nextShowTimeSeconds/3600);
45 var nextMinutes=parseInt((nextShowTimeSeconds-nextHours*3600)/60);
46 var nextSeconds=nextShowTimeSeconds%60;
47
48 var curHours=parseInt(curShowTimeSeconds/3600);
49 var curMinutes=parseInt((curShowTimeSeconds-curHours * 3600)/60);
50 var curSeconds=curShowTimeSeconds%60;
51
52 if(nextSeconds!=curSeconds){
53 //小球
54 if( parseInt(curHours/10) != parseInt(nextHours/10) ){
55 addBalls( MARGIN_LIFT + 0 , MARGIN_TOP , parseInt(curHours/10) );
56 }
57 if( parseInt(curHours%10) != parseInt(nextHours%10) ){
58 addBalls( MARGIN_LIFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(curHours/10) );
59 }
60
61 if( parseInt(curMinutes/10) != parseInt(nextMinutes/10) ){
62 addBalls( MARGIN_LIFT + 39*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes/10) );
63 }
64 if( parseInt(curMinutes%10) != parseInt(nextMinutes%10) ){
65 addBalls( MARGIN_LIFT + 54*(RADIUS+1) , MARGIN_TOP , parseInt(curMinutes%10) );
66 }
67
68 if( parseInt(curSeconds/10) != parseInt(nextSeconds/10) ){
69 addBalls( MARGIN_LIFT + 78*(RADIUS+1) , MARGIN_TOP , parseInt(curSeconds/10) );
70 }
71 if( parseInt(curSeconds%10) != parseInt(nextSeconds%10) ){
72 addBalls( MARGIN_LIFT + 93*(RADIUS+1) , MARGIN_TOP , parseInt(nextSeconds%10) );
73 }
74
75 //更新时间
76 curShowTimeSeconds=nextShowTimeSeconds;
77 }
78 //更新小球的速度
79 updateBalls();
80
81 }
82
83 function updateBalls(){
84 for( var i = 0 ; i < balls.length ; i ++ ){
85 balls[i].x += balls[i].vx;
86 balls[i].y += balls[i].vy;
87 balls[i].vy += balls[i].g;
88 if( balls[i].y >= WINDOW_HEIGHT-RADIUS ){
89 balls[i].y = WINDOW_HEIGHT-RADIUS;
90 balls[i].vy = - balls[i].vy*0.75;
91 }
92 }
93
94 var cnt=[];
95 for(var i=0;i<balls.length;i++){
96 if(balls[i].x-RADIUS>0&&balls[i].x+RADIUS<WINDOW_WIDTH){
97 cnt.push(balls[i]);
98 }
99 }
100 balls=cnt;
101
102 }
103
104 function addBalls( x , y , num ){
105 for( var i=0;i<digit[num].length;i++)
106 for(var j=0;j<digit[num][i].length;j++)
107 if( digit[num][i][j] == 1 ){
108 var aBall = {
109 x:x+j*2*(RADIUS+1)+(RADIUS+1),
110 y:y+i*2*(RADIUS+1)+(RADIUS+1),
111 g:1.5+Math.random(),
112 vx:Math.pow( -1 , Math.ceil( Math.random()*1000 ) ) * 4,
113 vy:-5,
114 color: colors[ Math.floor( Math.random()*colors.length ) ]
115 };
116 balls.push(aBall);
117 }
118 }
119
120 function getCurrentShowTimeSeconds() {
121 var curTime=new Date();
122 var ret=curTime.getHours()*3600+curTime.getMinutes()*60+curTime.getSeconds();
123 return ret;
124 }
125
126 function render(cxt) {
127
128 cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);//对整个画布进行刷新,防止新画的跟以前画的叠加
129 var hours=parseInt(curShowTimeSeconds/3600);
130 var minutes=parseInt((curShowTimeSeconds-hours * 3600)/60);
131 var seconds=curShowTimeSeconds%60;
132
133 renderDigit(MARGIN_LIFT,MARGIN_TOP,parseInt(hours/10),cxt);
134 renderDigit(MARGIN_LIFT+15*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),cxt);
135 renderDigit(MARGIN_LIFT+30*(RADIUS+1),MARGIN_TOP,10,cxt);
136 renderDigit(MARGIN_LIFT+39*(RADIUS+1),MARGIN_TOP,parseInt(minutes/10),cxt);
137 renderDigit(MARGIN_LIFT+54*(RADIUS+1),MARGIN_TOP,parseInt(minutes%10),cxt);
138 renderDigit(MARGIN_LIFT+69*(RADIUS+1),MARGIN_TOP,parseInt(10),cxt);
139 renderDigit(MARGIN_LIFT+78*(RADIUS+1),MARGIN_TOP,parseInt(seconds/10),cxt);
140 renderDigit(MARGIN_LIFT+93*(RADIUS+1),MARGIN_TOP,parseInt(seconds%10),cxt);
141
142 for(var i=0;i<balls.length;i++){
143 cxt.fillStyle=balls[i].color;
144
145 cxt.beginPath();
146 cxt.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true);
147 cxt.closePath();
148
149 cxt.fill();
150 }
151
152 }
153
154 function renderDigit(x,y,num,cxt) {
155 cxt.fillStyle="rgb(0,102,153)";
156
157 for(var i=0;i<digit[num].length;i++)
158 for(var j=0;j<digit[num][i].length;j++)
159 if(digit[num][i][j]==1){
160 cxt.beginPath();
161 cxt.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI);
162 cxt.closePath();
163
164 cxt.fill()
165 }
166 }
现在的时间,效果图。
至此,完成了canvas的动画基础!