鼠标左键单击生成一个小球, 按下鼠标左键并移动鼠标生成一串小球, 鼠标右键清除全部小球
注意: 一个窗口放太多小球会崩溃如果在当前窗口下已经有很多小球的情况下再切换到更小窗口, 也会崩溃
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width">
- <title>
- Ball
- </title>
- <style>
- html,body,canvas { width: 100vw; height: 100vh; cursor: crosshair; background:
- #EFEFEF; overflow: hidden; }
- </style>
- </head>
- <body>
- <canvas>
- </canvas>
- <script>
- var canvas = document.querySelector("canvas");
- var width = canvas.width = canvas.offsetWidth;
- var height = canvas.height = canvas.offsetHeight;
- var ctx = canvas.getContext("2d");
- var balls = [];
- var count = 0;
- var limit = 10;
- var maxRadius = 40;
- var isDown = false;
- var colors = ["#D90866", "#E87E0C", "#FF0000", "#8B0CE8", "#0D68FF"];
- window.addEventListener("resize",
- function() {
- canvas = document.querySelector("canvas");
- width = canvas.width = canvas.offsetWidth;
- height = canvas.height = canvas.offsetHeight;
- },
- false);
- canvas.addEventListener("contextmenu",
- function(e) {
- if (!e) e = window.event;
- e.preventDefault();
- balls = [];
- },
- false);
- canvas.addEventListener("mousedown",
- function(e) {
- if (!e) e = window.event;
- if (e.button == 0) isDown = true;
- },
- false);
- canvas.addEventListener("mouseup",
- function(e) {
- if (!e) e = window.event;
- isDown = false;
- },
- false);
- canvas.addEventListener("click",
- function(e) {
- if (!e) e = window.event;
- var x = e.clientX - 8;
- var y = e.clientY - 8;
- balls.push(new Ball(x, y));
- },
- false);
- canvas.addEventListener("mousemove",
- function(e) {
- if (!e) e = window.event;
- if (isDown) {
- var x = e.clientX - 8;
- var y = e.clientY - 8;
- balls.push(new Ball(x, y));
- }
- },
- false);
- function random(n) {
- return Math.floor(Math.random() * n);
- }
- function Ball(x, y) {
- this.x = x;
- this.y = y;
- this.vx = 3 * (Math.random() + Math.random() + Math.random() - 1.5);
- this.vy = 3 * (Math.random() + Math.random() + Math.random() - 1.5);
- this.radius = 5;
- this.m = this.radius * 0.5;
- this.color = colors[random(colors.length)];
- }
- function ballDraw() {
- for (var i = 0; i < balls.length; i++) {
- var ball = balls[i];
- var radius = ball.radius;
- var radgradX = ball.x - radius * 0.5;
- var radgradY = ball.y - radius * 0.5;
- var radgradR1 = radius * 0.02;
- var radgradR2 = radius * 2;
- var radgrad = ctx.createRadialGradient(radgradX, radgradY, radgradR1, radgradX, radgradY, radgradR2);
- radgrad.addColorStop(0, "#F7F7F7");
- radgrad.addColorStop(0.8, ball.color);
- radgrad.addColorStop(1, ball.color);
- ctx.fillStyle = radgrad;
- ctx.shadowColor = "#403938";
- ctx.beginPath();
- ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
- ctx.shadowOffsetX = ball.radius * 0.08;
- ctx.shadowOffsetY = ball.radius * 0.08;
- ctx.shadowBlur = ball.radius * 0.2;
- ctx.closePath();
- ctx.fill();
- }
- }
- function ballMove() {
- for (var i = 0; i < balls.length; i++) {
- var ball = balls[i];
- if (ball.radius >= maxRadius) {
- ball.x += ball.vx;
- ball.y += ball.vy;
- if (ball.x - ball.radius < 0) {
- ball.x = ball.radius;
- ball.vx *= -1;
- }
- if (ball.x + ball.radius > width) {
- ball.x = width - ball.radius;
- ball.vx *= -1;
- }
- if (ball.y - ball.radius < 0) {
- ball.y = ball.radius;
- ball.vy *= -1;
- }
- if (ball.y + ball.radius > height) {
- ball.y = height - ball.radius;
- ball.vy *= -1;
- }
- }
- }
- }
- function ballBigger() {
- for (var i = 0; i < balls.length; i++) {
- var ball = balls[i];
- if (ball.radius < maxRadius) {
- ball.radius += 0.5;
- }
- }
- }
- function ballCollision() {
- for (var i = 0; i < balls.length; i++) {
- var ball1 = balls[i];
- for (var j = i + 1; j < balls.length; j++) {
- var ball2 = balls[j];
- if (ball1.radius + ball2.radius >= maxRadius * 2) {
- var dx = ball1.x - ball2.x;
- var dy = ball1.y - ball2.y;
- var dds = dx * dx + dy * dy;
- var dm = ball1.radius + ball2.radius;
- var dms = dm * dm;
- if (dds < dms) {
- var angle = Math.atan2(dy, dx);
- var dist = Math.sqrt(dds);
- var depth = (dist - dm) / dist;
- ball1.x -= dx * depth * 0.5;
- ball1.y -= dy * depth * 0.5;
- ball2.x += dx * depth * 0.5;
- ball2.y += dy * depth * 0.5;
- var v1 = Math.sqrt(ball1.vx * ball1.vx + ball1.vy * ball1.vy);
- var v2 = Math.sqrt(ball2.vx * ball2.vx + ball2.vy * ball2.vy);
- var a1 = Math.atan2(ball1.vy, ball1.vx);
- var a2 = Math.atan2(ball2.vy, ball2.vx);
- var rvx1 = v1 * Math.cos(a1 - angle);
- var rvy1 = v1 * Math.sin(a1 - angle);
- var rvx2 = v2 * Math.cos(a2 - angle);
- var rvy2 = v2 * Math.sin(a2 - angle);
- var evx1 = ((ball1.m - ball2.m) * rvx1 + 2 * ball2.m * rvx2) / (ball1.m + ball2.m);
- var evx2 = ((ball2.m - ball1.m) * rvx2 + 2 * ball1.m * rvx1) / (ball1.m + ball2.m);
- var evy1 = rvy1;
- var evy2 = rvy2;
- ball1.vx = Math.cos(angle) * evx1 + Math.cos(angle + Math.PI / 2) * evy1;
- ball1.vy = Math.sin(angle) * evx1 + Math.sin(angle + Math.PI / 2) * evy1;
- ball2.vx = Math.cos(angle) * evx2 + Math.cos(angle + Math.PI / 2) * evy2;
- ball2.vy = Math.sin(angle) * evx2 + Math.sin(angle + Math.PI / 2) * evy2;
- }
- }
- }
- }
- } (function animate() {
- ctx.clearRect(0, 0, width, height);
- if (count < limit) {
- count++;
- balls.push(new Ball(random(width), random(height)));
- }
- ballBigger();
- ballMove();
- ballCollision();
- ballDraw();
- requestAnimationFrame(animate);
- })();
- </script>
- </body>
- </html>
来源: http://www.qdfuns.com/article/45516/07120d40dba93bcf95b73b6e0f519b22.html