Multiple Bouncing Balls
Starting point of a class exercise where we make incremental improvements.
HTML
<h1>Bouncing Balls</h1>
<p>These bouncing balls are made with completely raw JavaScript,
just with divs. We don't use jQuery. We don't use canvas.</p>
<div id="canvas"></div>
CSS
body {
text-align: center;
}
#canvas {
position: relative;
background-color: #ccddcc;
margin: 1em auto;
}
.ball {
background-color: black;
position: absolute;
display: inline-block;
border-radius: 50%;
}
JavaScript
"use strict";
// This code is not optimized.
// It is used to teach vector math.
Array.prototype.dot = function (v) {
return this[0] * v[0] + this[1] * v[1];
}
Array.prototype.minus = function (v) {
return [this[0]-v[0], this[1]-v[1]];
}
Array.prototype.plus = function (v) {
return [this[0]+v[0], this[1]+v[1]];
}
Array.prototype.times = function(s) {
return [s*this[0], s*this[1]];
}
Array.prototype.normalize = function () {
var length = Math.sqrt(this[0]*this[0] + this[1]*this[1]);
return [this[0]/length, this[1]/length];
}
Array.prototype.distanceTo = function (q) {
var dx = this[0] - q[0];
var dy = this[1] - q[1]
return Math.sqrt(dx*dx + dy*dy);
}
Array.prototype.reflect = function (n) {
n = n.normalize();
return this.minus(n.times(2*this.dot(n)));
}
var canvas = {
element: document.getElementById('canvas'),
width: 600,
height: 400,
initialize: function () {
this.element.style.width = this.width + 'px';
this.element.style.height = this.height + 'px';
document.body.appendChild(this.element);
}
};
var Ball = {
create: function (color, x, y, dx, dy) {
var newBall = Object.create(this);
newBall.pos = [x,y];
newBall.dir = [dx,dy];
newBall.width = 40;
newBall.height = 40;
newBall.element = document.createElement('div');
newBall.element.style.backgroundColor = color;
newBall.element.style.width = newBall.width + 'px';
newBall.element.style.height = newBall.height + 'px';
newBall.element.className += ' ball';
newBall.width = parseInt(newBall.element.style.width);
newBall.height = parseInt(newBall.element.style.height);
canvas.element.appendChild(newBall.element);
return newBall;
},
draw: function () {
this.element.style.left = this.pos[0] + 'px';
this.element.style.top = this.pos[1] + 'px';
},
center: function () {
...