JavaScript
語言:
JaveScriptBabelCoffeeScript
确定
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var c = document.getElementById("canv");
var $ = c.getContext("2d");
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
window.addEventListener('load', resize);
window.addEventListener('resize', resize, false);
window.addEventListener('mousedown', msdn, false);
window.addEventListener('mousemove', msmv, false);
window.addEventListener('mouseup', msup, false);
function resize() {
c.width = w = window.innerWidth;
c.height = h = window.innerHeight;
c.style.position = 'absolute';
c.style.left = (window.innerWidth - w) *
.01 + 'px';
c.style.top = (window.innerHeight - h) *
.01 + 'px';
var cnt = w / 20 | 0;
var len = balls.length;
var n = len;
while (n--) {
if (n > cnt) {
balls[n].remove();
balls.splice(n, 1);
} else {
break;
}
}
for (var i = 0, p = cnt - len; i < p; i++) {
balls.push(new Ball(Math.random() * w, -100));
}
};
function Ball(x, y, rad) {
this.x = x;
this.y = y;
this.rad = (rad || Math.random() * 40 + 20) | 0;
this.vel_x = Math.random() * 30 - 15;
this.vel_y = Math.random() * 30 - 15;
this.red = Math.random() * 255 | 255;
this.green = Math.random() * 155 | 5;
this.blue = Math.random() * 255 | 55;
this.fillStyle = "rgba(" + this.red + "," + this.green + "," + this.blue + "," + 1 + ")";
this.stick = false;
}
Ball.prototype.draw = function() {
$.beginPath();
$.fillStyle = this.fillStyle;
$.arc(this.x, this.y, this.rad, 0, Math.PI * 2, true);
$.fill();
};
Ball.prototype.remove = function() {
$.beginPath();
$.fillStyle = 'hsla(0,0%,0%,1)';
$.arc(this.x, this.y, this.rad + 1, 0, Math.PI * 2, true);
$.fill();
};
Ball.prototype.hit = function(x, y) {
var side_x = x - this.x;
var side_y = y - this.y;
return Math.sqrt(side_x * side_x + side_y * side_y) < this.rad;
};
var ball_ = null;
function msdn(e) {
var x = e.clientX;
var y = e.clientY;
for (i = 0; i < balls.length; i++) {
var ball = balls[i];
if (ball.hit(x, y)) {
ball.stick = true;
ball_ = ball;
break;
}
}
return false;
};
function msmv(e) {
if (ball_) {
var x_ = ball_.x;
var y_ = ball_.y;
ball_.remove();
ball_.x = e.clientX;
ball_.y = e.clientY;
ball_.draw();
ball_.vel_x = ball_.x - x_;
ball_.vel_y = ball_.y - y_;
}
};
function msup(e) {
if (ball_) {
ball_.stick = false;
ball_ = null;
}
};
var center = {
x: w / 2,
y: h / 2
};
var balls = [];
var num = 10;
var grav = 1.5;
var bounce = -0.65;
var frict = 0.98;
var react = 0.9;
for (var i = 0; i < num; i++) {
balls.push(new Ball(Math.random() * w, -100));
}
setInterval(run, 33);
window.requestAnimFrame(run);
function run() {
for (var i = 0; i < balls.length - 1; i++) {
var ball_a = balls[i];
for (var j = i + 1; j < balls.length; j++) {
var ball_b = balls[j];
var dx = ball_b.x - ball_a.x;
var dy = ball_b.y - ball_a.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var minDist = ball_a.rad + ball_b.rad;
if (dist < minDist) {
var ang = Math.atan2(dy, dx);
var this_x = ball_a.x + Math.cos(ang) * minDist;
var this_y = ball_a.y + Math.sin(ang) * minDist;
var ang_x = (this_x - ball_b.x) * react;
var ang_y = (this_y - ball_b.y) * react;
if (!ball_a.stick) {
ball_a.vel_x -= ang_x;
ball_a.vel_y -= ang_y;
}
if (!ball_b.stick) {
ball_b.vel_x += ang_x;
ball_b.vel_y += ang_y;
}
}
}
}
for (i = 0; i < balls.length; i++) {
var ball = balls[i];
if (!ball.stick) {
ball.remove();
move(ball);
ball.draw();
}
}
}
function move(ball) {
ball.vel_x *= frict;
ball.vel_y *= frict;
ball.vel_y += grav;
ball.x += ball.vel_x;
ball.y += ball.vel_y;
if (ball.x > w - ball.rad) {
ball.x = w - ball.rad;
ball.vel_x *= bounce;
} else if (ball.x < ball.rad) {
ball.x = ball.rad;
ball.vel_x *= bounce;
} else if (ball.y > h - ball.rad) {
ball.y = h - ball.rad;
ball.vel_y *= bounce;
}
}