天天看点

html 圆球的百分比,HTML5 Canvas 紧张而拥挤的圆球

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;

}

}