首页 > 代码库 > 【鸡年大吉】,不知道写点啥,放个demo(小球碰撞)吧,有兴趣的看看

【鸡年大吉】,不知道写点啥,放个demo(小球碰撞)吧,有兴趣的看看

最初的想法是仿写win7的泡泡屏保效果,但是对于小球的斜碰问题一直没搞明白(如果你会这个,欢迎留言或者做个demo),所以只是简单处理了碰撞后的速度,有时候会看起来很搞笑~~~funny guy

 

话不多说,先上demo

https://win7killer.github.io/can_ps/src/demo/ball.html

效果如下:

技术分享

code:

  1 <!DOCTYPE html>
  2 <html lang="zh">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>Document</title>
  9     <style>
 10         * {
 11             margin: 0;
 12             padding: 0;
 13         }
 14         
 15         html {
 16             height: 100%;
 17         }
 18         
 19         body {
 20             width: 100%;
 21             height: 100%;
 22             background: #333;
 23             background: url(./img/6.jpg) no-repeat 0 0;
 24             background-size: cover;
 25         }
 26         
 27         canvas {
 28             display: block;
 29         }
 30     </style>
 31 </head>
 32 
 33 <body>
 34     <canvas id="can" width=0 height=0></canvas>
 35     <script>
 36         var ballsNum = 20;
 37         window.onload = function() {
 38 
 39             var can = document.getElementById(can);
 40             can.width = document.body.offsetWidth;
 41             can.height = document.body.offsetHeight;
 42             var ctx = can.getContext(2d);
 43             var ballR = Math.floor(can.height / 15);
 44             ctx.shadowColor = rgba(0,0,0,.3);
 45             ctx.shadowOffsetX = ballR / 5;
 46             ctx.shadowOffsetY = ballR / 5;
 47             // ctx.shadowBlur = ballR / 10 > 5 ? ballR / 10 : 5;
 48             ctx.shadowBlur = 16;
 49 
 50             var aObj = randomBall(ballsNum);
 51             var raf = window.requestAnimationFrame(loop);
 52 
 53             function loop() {
 54                 ctx.clearRect(0, 0, can.width, can.height);
 55                 for (var i = 0, l = aObj.length; i < l; i++) {
 56                     fnChange(aObj[i]);
 57                     checkPeng(aObj, i);
 58                 }
 59                 if (raf) {
 60                     raf = window.requestAnimationFrame(loop);
 61                 }
 62             }
 63 
 64             //  改变圆心坐标
 65             function fnChange(obj) {
 66                 drawArc(obj);
 67                 obj.x += obj.sx * 10 / 4;
 68                 obj.y += obj.sy * 5 / 4;
 69 
 70                 if (obj.x >= can.width - ballR) {
 71                     obj.x = can.width - ballR;
 72                     obj.sx = -1 * obj.sx;
 73                 } else if (obj.x <= ballR) {
 74                     obj.x = ballR;
 75                     obj.sx = -1 * obj.sx;
 76                 }
 77                 if (obj.y >= can.height - ballR) {
 78                     obj.y = can.height - ballR;
 79                     obj.sy = -1 * obj.sy;
 80                 } else if (obj.y <= ballR) {
 81                     obj.y = ballR;
 82                     obj.sy = -1 * obj.sy;
 83                 }
 84             }
 85             //画圆
 86             function drawArc(obj) {
 87                 ctx.save();
 88                 ctx.beginPath();
 89                 ctx.arc(obj.x % can.width, obj.y % can.height, ballR, 0, 2 * Math.PI);
 90                 ctx.closePath();
 91 
 92                 var grd = ctx.createRadialGradient(obj.x - ballR * 3 / 10, obj.y - ballR * 4 / 10, ballR / 8, obj.x - ballR * 4 / 10, obj.y - ballR * 4 / 10, ballR * 16 / 10);
 93                 grd.addColorStop(0, "rgba(255,255,255,1)");
 94                 grd.addColorStop(1, obj.scolor);
 95                 ctx.fillStyle = grd;
 96                 ctx.fill();
 97                 ctx.restore();
 98             }
 99 
100             function randomBall(num) {
101                 var barr = [];
102                 var ball;
103                 for (var i = 0; i < num || 0; i++) {
104                     ball = {};
105                     ball.x = Math.random() * (can.width - ballR * 2) + ballR;
106                     ball.y = Math.random() * (can.height - ballR * 2) + ballR;
107                     ball.sx = Math.random() * 6 - 6 / 2;
108                     ball.sy = Math.random() * 6 - 6 / 2;
109                     var scr = Math.round(Math.random() * 200 + 50);
110                     var scg;
111                     var scb;
112                     if (scr > 200) {
113                         if (Math.random() > 1) {
114                             scg = Math.round(Math.random() * 150 + 50);
115                             scb = Math.round(Math.random() * 200 + 50);
116                         } else {
117                             scb = Math.round(Math.random() * 150 + 50);
118                             scg = Math.round(Math.random() * 200 + 50);
119                         }
120                     } else {
121                         scg = Math.round(Math.random() * 200 + 50);
122                         scb = Math.round(Math.random() * 200 + 50);
123                     }
124                     ball.scolor = rgba( + [scr, scg, scb, 1].join(,) + );
125                     barr.push(ball);
126                 }
127                 return barr;
128             }
129 
130             //碰撞检测
131             function checkPeng(arr, i) {
132                 var j, len;
133 
134                 for (j = 0, len = arr.length; j < len; j++) {
135                     if (i === j) {
136                         continue;
137                     }
138                     var ca = {
139                         x: arr[i].x - arr[j].x,
140                         y: arr[i].y - arr[j].y
141                     }
142                     var z = Math.sqrt(Math.pow(ca.x, 2) + Math.pow(ca.y, 2));
143                     var cha = z - ballR * 2;
144                     if (cha <= 0) {
145                         if (arr[i].x < arr[j].x) {
146                             arr[i].x += cha;
147                         } else {
148                             arr[i].x += -cha;
149                         }
150                         if (arr[i].y < arr[j].y) {
151                             arr[i].y += cha;
152                         } else {
153                             arr[i].y += -cha;
154                         }
155                         //arr[i].sy = -1*arr[i].sy;
156                         var iTY = arr[i].sy;
157                         arr[i].sy = 1 * arr[j].sy;
158                         arr[j].sy = iTY;
159                         //arr[i].sx = -1*arr[i].sx;
160                         var iTX = arr[i].sx;
161                         arr[i].sx = 1 * arr[j].sx;
162                         arr[j].sx = iTX;
163                     }
164                 }
165             }
166         }
167     </script>
168 </body>
169 
170 </html>

 

然后是加强版的透明泡泡

https://win7killer.github.io/can_ps/src/demo/ball_1.html

效果如下:

技术分享

 

code:

  1 <!DOCTYPE html>
  2 <html lang="zh">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>Document</title>
  9     <style>
 10         * {
 11             margin: 0;
 12             padding: 0;
 13         }
 14 
 15         html {
 16             height: 100%;
 17         }
 18 
 19         body {
 20             width: 100%;
 21             height: 100%;
 22             background: #333;
 23             background: url(./img/6.jpg) no-repeat 0 0;
 24             background-size: cover;
 25         }
 26 
 27         canvas {
 28             display: block;
 29         }
 30     </style>
 31 </head>
 32 
 33 <body>
 34     <canvas id="can" width=0 height=0></canvas>
 35     <script>
 36         var ballsNum = 20;
 37         window.onload = function() {
 38 
 39             var can = document.getElementById(can);
 40             can.width = document.body.offsetWidth;
 41             can.height = document.body.offsetHeight;
 42             var ctx = can.getContext(2d);
 43             var ballR = Math.floor(can.height / 15);
 44             ctx.shadowColor = rgba(0,0,0,.3);
 45             ctx.shadowOffsetX = ballR / 5;
 46             ctx.shadowOffsetY = ballR / 5;
 47             // ctx.shadowBlur = ballR / 10 > 5 ? ballR / 10 : 5;
 48             ctx.shadowBlur = 16;
 49 
 50             var aObj = randomBall(ballsNum);
 51             var raf = window.requestAnimationFrame(loop);
 52             function loop() {
 53                 ctx.clearRect(0, 0, can.width, can.height);
 54                 for (var i = 0, l = aObj.length; i < l; i++) {
 55                     fnChange(aObj[i]);
 56                     checkPeng(aObj, i);
 57                 }
 58                 if (raf) {
 59                     raf = window.requestAnimationFrame(loop);
 60                 }
 61             }
 62 
 63             //  改变圆心坐标
 64             function fnChange(obj) {
 65                 drawArc(obj);
 66                 obj.x += obj.sx * 10 / 4;
 67                 obj.y += obj.sy * 5 / 4;
 68 
 69                 if (obj.x >= can.width - ballR) {
 70                     obj.x = can.width - ballR;
 71                     obj.sx = -1 * obj.sx;
 72                 } else if (obj.x <= ballR) {
 73                     obj.x = ballR;
 74                     obj.sx = -1 * obj.sx;
 75                 }
 76                 if (obj.y >= can.height - ballR) {
 77                     obj.y = can.height - ballR;
 78                     obj.sy = -1 * obj.sy;
 79                 } else if (obj.y <= ballR) {
 80                     obj.y = ballR;
 81                     obj.sy = -1 * obj.sy;
 82                 }
 83             }
 84             //画圆
 85             function drawArc(obj) {
 86                 ctx.save();
 87                 ctx.beginPath();
 88                 ctx.arc(obj.x % can.width, obj.y % can.height, ballR, 0, 2 * Math.PI);
 89                 ctx.closePath();
 90 
 91                 var grd1 = ctx.createRadialGradient(
 92                     obj.x,
 93                     obj.y,
 94                     ballR / 2,
 95                     obj.x,
 96                     obj.y,
 97                     ballR * 13 / 10
 98                 );
 99                 // grd1.addColorStop(0, "rgba(255,255,255,1)");
100                 grd1.addColorStop(0, "rgba(255,255,255,0)");
101                 grd1.addColorStop(1, obj.scolor);
102                 ctx.fillStyle = grd1;
103                 ctx.fill();
104                 ctx.restore();
105 
106                 var grd = ctx.createRadialGradient(obj.x - ballR * 3 / 10, obj.y - ballR * 4 / 10, ballR / 8, obj.x - ballR * 4 / 10, obj.y - ballR * 4 / 10, ballR * 16 / 10);
107                 grd.addColorStop(0, "rgba(255,255,255,1)");
108                 grd.addColorStop(0.2, "rgba(255,255,255,0)");
109                 grd.addColorStop(1, "rgba(255,255,255,0)");
110                 // grd.addColorStop(1, obj.scolor);
111                 ctx.fillStyle = grd;
112                 ctx.save();
113                 ctx.shadowColor = rgba(0,0,0,.0);
114                 ctx.fill();
115                 ctx.restore();
116             }
117 
118             function randomBall(num) {
119                 var barr = [];
120                 var ball;
121                 for (var i = 0; i < num || 0; i++) {
122                     ball = {};
123                     ball.x = Math.random() * (can.width - ballR * 2) + ballR;
124                     ball.y = Math.random() * (can.height - ballR * 2) + ballR;
125                     ball.sx = Math.random() * 6 - 6 / 2;
126                     ball.sy = Math.random() * 6 - 6 / 2;
127                     var scr = Math.round(Math.random() * 200 + 50);
128                     var scg;
129                     var scb;
130                     if (scr > 200) {
131                         if (Math.random() > 1) {
132                             scg = Math.round(Math.random() * 150 + 50);
133                             scb = Math.round(Math.random() * 200 + 50);
134                         } else {
135                             scb = Math.round(Math.random() * 150 + 50);
136                             scg = Math.round(Math.random() * 200 + 50);
137                         }
138                     } else {
139                         scg = Math.round(Math.random() * 200 + 50);
140                         scb = Math.round(Math.random() * 200 + 50);
141                     }
142                     ball.scolor = rgba( + [scr, scg, scb, 1].join(,) + );
143                     barr.push(ball);
144                 }
145                 return barr;
146             }
147 
148             //碰撞检测
149             function checkPeng(arr, i) {
150                 var j, len;
151 
152                 for (j = 0, len = arr.length; j < len; j++) {
153                     if (i === j) {
154                         continue;
155                     }
156                     var ca = {
157                         x: arr[i].x - arr[j].x,
158                         y: arr[i].y - arr[j].y
159                     }
160                     var z = Math.sqrt(Math.pow(ca.x, 2) + Math.pow(ca.y, 2));
161                     var cha = z - ballR * 2;
162                     if (cha <= 0) {
163                         if (arr[i].x < arr[j].x) {
164                             arr[i].x += cha;
165                         } else {
166                             arr[i].x += -cha;
167                         }
168                         if (arr[i].y < arr[j].y) {
169                             arr[i].y += cha;
170                         } else {
171                             arr[i].y += -cha;
172                         }
173                         //arr[i].sy = -1*arr[i].sy;
174                         var iTY = arr[i].sy;
175                         arr[i].sy = 1 * arr[j].sy;
176                         arr[j].sy = iTY;
177                         //arr[i].sx = -1*arr[i].sx;
178                         var iTX = arr[i].sx;
179                         arr[i].sx = 1 * arr[j].sx;
180                         arr[j].sx = iTX;
181                     }
182                 }
183             }
184         }
185     </script>
186 </body>
187 
188 </html>

 

就这样吧,canvas写了一些有意思的demo,但是没有系统的可以写成博客的东西,之后会慢慢整理一下介绍给大家~

 

最后,祝大家鸡年大吉吧,升职涨薪。

 

【鸡年大吉】,不知道写点啥,放个demo(小球碰撞)吧,有兴趣的看看