(function (w, d) {
var trueName = 'COLLIDE_O_SCOPE';
w[trueName] = {};
var $ = w[trueName];
$.d = d;
$.w = w;
$.s = {};
$.f = function() {
return {
behavior : function() {
// an array to hold all circles
$.v = [];
// initial make and draw
for (var i = 0; i < $.a.count; i++) {
$.f.makeCircle(i);
}
// we'll try for 30 frames per second
setInterval(trueName + ".f.draw()", 33);
},
makeCircle : function(i, x, y) {
// each circle has its own object member of the master $.v array
$.v[i] = {};
// initial X location
if (!x) {
// random
$.v[i].x = $.f.getRnd($.a.width);
} else {
// this circle was added by viewer click
$.v[i].x = x;
}
// initial X vector, 1 to 6 pixels per turn
$.v[i].dx = $.f.getRnd(6, 1);
// initial Y location
if (!y) {
// random
$.v[i].y = $.f.getRnd($.a.height);
} else {
// this circle was added by viewer click
$.v[i].y = y;
}
// initial Y vector, 1 to 6 pixels per turn
$.v[i].dy = $.f.getRnd(6, 1);
// number of rings in this circle
var n = $.f.getRnd($.a.addSize, $.a.baseSize);
// array to hold rings
$.v[i].c = [];
for (var j = 0; j < n; j++) {
// object to hold colors for each ring
$.v[i].c[j] = {};
// red
$.v[i].c[j].r = $.f.getRnd($.a.maxColor);
// green
$.v[i].c[j].g = $.f.getRnd($.a.maxColor);
// blue
$.v[i].c[j].b = $.f.getRnd($.a.maxColor);
}
},
getRnd: function(r, m) {
// no range? use 1
if (!r) { r = 1; }
// no minimum? use 0
if (!m) { m = 0; }
// return a random number between 0 and the specified range, plus the minimum, rounded down
return Math.floor(Math.random() * r) + m;
},
draw: function() {
// set our background color
$.c.fillStyle = 'rgba(' + $.a.backgroundRed + ',' + $.a.backgroundGreen + ',' + $.a.backgroundBlue + ',' + $.a.backgroundAlpha + ')';
// draw our background
$.c.fillRect(0,0,$.a.width,$.a.height);
// get length of circle array
var n = $.v.length;
// draw visible circles
for (var i = $.a.firstCirc; i < n; i++) {
var g = $.a.grid * 5;
var ix = parseInt($.v[i].x / g, 10);
var iy = parseInt($.v[i].y / g, 10);
// skanky punk-rock collision detection
for (var j = $.a.firstCirc; j < n; j++) {
if (i !== j) {
var jx = parseInt($.v[j].x / g, 10);
var jy = parseInt($.v[j].y / g, 10);
// are both numbers within g pixels of each other?
if (ix === jx && iy === jy) {
// change directions
$.v[i].dx = $.f.getRnd(6, 1);
$.v[i].dy = $.f.getRnd(6, 1);
$.v[j].dx = $.f.getRnd(6, 1);
$.v[j].dy = $.f.getRnd(6, 1);
}
}
}
// offscreen? wrap around
$.v[i].x = ($.v[i].x + $.v[i].dx) % $.a.width;
$.v[i].y = ($.v[i].y + $.v[i].dy) % $.a.height;
// draw all rings in this circle
for (var k = 1; k < $.v[i].c.length; k++) {
$.f.drawRings({
"x":$.v[i].x,
"y":$.v[i].y,
"z":(k * ($.a.grid/2) - 5),
"r":$.v[i].c[k].r,
"g":$.v[i].c[k].g,
"b":$.v[i].c[k].b,
"a":$.a.ringAlpha
});
}
}
},
drawRings : function(c) {
$.c.fillStyle = 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')';
// draw all eight possible reflections of this circle
$.f.circ(c.x, c.y, c.z);
$.f.circ($.a.width - c.x, c.y, c.z);
$.f.circ(c.x, $.a.height - c.y, c.z);
$.f.circ($.a.width - c.x, $.a.height - c.y, c.z);
$.f.circ(c.y, c.x, c.z);
$.f.circ($.a.width - c.y, c.x, c.z);
$.f.circ(c.y, $.a.height - c.x, c.z);
$.f.circ($.a.width - c.y, $.a.height - c.x, c.z);
},
circ : function(x, y, r) {
$.c.beginPath();
// 0 = start, $.a.p = 2 x pi, for full circle
$.c.arc(x, y, r, 0, $.a.p, true);
$.c.closePath();
$.c.fill();
},
up : function(v) {
var e = v || window.event;
var t = $.v.length;
// starting X and Y are where you clicked
$.f.makeCircle(t, e.clientX - $.x, e.clientY - $.y);
// keep the number of circles on the screen constant
$.a.firstCirc++;
},
houseKeep: function(){
// arg store
$.a = {};
// were any args sent from the script?
// load some defaults
var defaults = {
"p":Math.PI * 2,
"height":300,
"width":300,
"count":20,
"addSize":5,
"baseSize":4,
"grid":14,
"maxColor":256,
"backgroundRed":0,
"backgroundGreen":0,
"backgroundBlue":0,
"backgroundAlpha":1,
"ringAlpha":".1"
};
for (var d in defaults) {
if ($.a[d] === undefined) {
$.a[d] = defaults[d];
}
}
// initially we draw all the circles
$.a.firstCirc = 0;
// make our canvas
var c = $.d.getElementsByTagName("CANVAS")[0];
c.id = trueName;
c.height = $.a.height;
c.width = $.a.width;
$.f.getCanvasPosition(c);
$.c = c.getContext('2d');
// if the viewer clicks, do something
c.onmouseup = $.f.up;
$.f.behavior();
},
getCanvasPosition : function(p) {
$.x = 0;
$.y = 0;
do {
$.x += p.offsetLeft;
$.y += p.offsetTop;
p = p.offsetParent;
} while (p.offsetParent);
},
init : function(thisScript) {
$.f.houseKeep();
$.s.main = $.d.getElementById('main');
var s = document.getElementsByTagName('SCRIPT')[0].textContent;
$.s.main.textContent = s;
}
};
}();
var thisScript = /collide.js$/;
if(typeof w.addEventListener !== 'undefined') {
w.addEventListener('load', function() { $.f.init(thisScript); }, false);
} else if(typeof w.attachEvent !== 'undefined') {
w.attachEvent('onload', function() { $.f.init(thisScript); });
}
})(window, document);