Skip to content

Instantly share code, notes, and snippets.

@ManasN
Forked from anonymous/Grid-2.markdown
Created December 11, 2014 15:14
Show Gist options
  • Save ManasN/7c670e12e6a37247767e to your computer and use it in GitHub Desktop.
Save ManasN/7c670e12e6a37247767e to your computer and use it in GitHub Desktop.
<canvas id="canvas"></canvas>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var W, H;
sizeCanvas();
var raf = requestAnimationFrame;
/*---------------------------------------------------------------------------*/
'floor|random|round|abs|sqrt|PI|atan2|sin|cos|pow|max|min'
.split('|')
.forEach(function(p) { this[p] = Math[p]; });
var TAU = PI*2;
function randint(n) { return floor(n*random()); }
function choose() { return arguments[randint(arguments.length)]; }
/*---------------------------------------------------------------------------*/
var running = false;
var time = 0;
function sizeCanvas() {
W = canvas.width = innerWidth;
H = canvas.height = innerHeight;
}
function loop() {
if (running) raf(loop);
draw();
time++;
}
document.onclick = function(e) {
running = false;
setTimeout(function() {
time = 0;
reset();
running = true;
raf(loop);
}, 100);
};
/*---------------------------------------------------------------------------*/
function Creeper(x, y, fn, depth) {
this.x = x;
this.y = y;
this.fn = (fn || chooseDirection());
this.depth = (depth || 0);
}
var directions = [
N, N, S, S, E, E, W_, W_,
NE1, NE2, NW1, NW2,
SE1, SE2, SW1, SW2
];
function chooseDirection(fns) {
if (fns) {
do { fn = chooseDirection(); } while(fns.indexOf(fn) > -1);
return fn;
}
return directions[randint(16)];
}
Creeper.prototype.animate = function(n) {
this.fn(this.x, this.y, n);
};
Creeper.prototype.spawn = function() {
var x, y;
switch (this.fn) {
case N: x = this.x; y = this.y - Length; break;
case S: x = this.x; y = this.y + Length; break;
case E: x = this.x + Length; y = this.y; break;
case W_: x = this.x - Length; y = this.y; break;
case NE1: case NE2:
x = this.x + Length; y = this.y - Length; break;
case NW1: case NW2:
x = this.x - Length; y = this.y - Length; break;
case SE1: case SE2:
x = this.x + Length; y = this.y + Length; break;
case SW1: case SW2:
x = this.x - Length; y = this.y + Length; break;
}
var dir = chooseDirection();
return new Creeper(x, y, dir, this.depth+1);
};
function N(x, y, n) { segment(x, y, x, y - n*Length); }
function S(x, y, n) { segment(x, y, x, y + n*Length); }
function E(x, y, n) { segment(x, y, x + n*Length, y); }
function W_(x, y, n) { segment(x, y, x - n*Length, y); }
function NE1(x, y, n) { arc(x, y-Length, TAU/4, 0, n, true); }
function NE2(x, y, n) { arc(x+Length, y , PI, 3*TAU/4, n, false); }
function NW1(x, y, n) { arc(x , y-Length, TAU/4, TAU/2, n, false); }
function NW2(x, y, n) { arc(x-Length, y , TAU, 3*TAU/4, n, true); }
function SE1(x, y, n) { arc(x , y+Length, 3*TAU/4, TAU, n, false); }
function SE2(x, y, n) { arc(x+Length, y , TAU/2, TAU/4, n, true); }
function SW1(x, y, n) { arc(x , y+Length, 3*TAU/4, TAU/2, n, true); }
function SW2(x, y, n) { arc(x-Length, y , 0, TAU/4, n, false); }
function jitter(n) {
return n + choose(-1, 0, 1);
}
function segment(x1, y1, x2, y2) {
x1 = jitter(x1);
x2 = jitter(x2);
y1 = jitter(y1);
y2 = jitter(y2);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineWidth = Thickness;
ctx.strokeStyle = Color;
ctx.stroke();
}
function arc(x, y, a1, a2, n, dir) {
x = jitter(x);
y = jitter(y);
ctx.beginPath();
ctx.arc(x, y, Length, a1, n*(a2-a1)+a1, dir);
ctx.lineWidth = Thickness;
ctx.strokeStyle = Color;
ctx.stroke();
}
/*---------------------------------------------------------------------------*/
var creepers;
var drawn;
var Length = 40;
var Thickness = 0.2;
var Color = 'rgba(23, 23, 23, 0.8);'
// Frames per cycle
var FPC = 20;
function reset() {
sizeCanvas();
ctx.clearRect(0, 0, W, H);
creepers = [new Creeper(floor(W/2), floor(H/2), N),
new Creeper(floor(W/2), floor(H/2), S),
new Creeper(floor(W/2), floor(H/2), E),
new Creeper(floor(W/2), floor(H/2), W_)];
}
function draw() {
var next = [];
for (var i = 0; i < creepers.length; i++) {
var c = creepers[i];
c.animate((time % FPC) / FPC);
}
if (time > 0 && time % FPC === 0) {
for (i = 0; i < creepers.length; i++) {
var c = creepers[i];
if (c.depth > 8) continue;
next.push(c.spawn());
if (random() < 0.1) next.push(c.spawn());
}
creepers = next;
}
}
reset();
running = true;
raf(loop);
body {
margin: 0;
padding: 0;
overflow: hidden;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment