Created
June 8, 2012 20:28
-
-
Save aitor/2897992 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
</head> | |
<body> | |
<canvas id="c"></canvas> | |
</body> | |
<script> | |
var canvas = document.getElementById('c'); | |
var w = canvas.width = innerWidth; | |
var h = canvas.height = innerHeight; | |
var ctx = canvas.getContext('2d'); | |
ctx.translate(w>>1, h>>1); | |
// vec2 | |
function vec2(x, y) { this.x = x; this.y = y; } | |
function madd(v, m, a) { | |
v.x += m*a.x | |
v.y += m*a.y; | |
} | |
function mov(v, a) { | |
v.x = a.x; | |
v.y = a.y; | |
} | |
function add(a, b) { return new vec2(a.x + b.x, a.y + b.y);} | |
function mul(a, b) { return new vec2(a*b.x, a*b.y);} | |
function length(a) { return Math.sqrt(a.x*a.x + a.y*a.y);} | |
function norm(b) { return mul(1.0/length(b), b) }; | |
function clone(a) { return new vec2(a.x, a.y); } | |
function v2(x, y) { return new vec2(x, y);} | |
function rot(v, ang) { | |
var c = Math.cos(ang); | |
var s = Math.sin(ang); | |
return v2(c*v.x - s*v.y, c*v.y + s*v.x); | |
} | |
function rndAng() { | |
var idx = (Math.random()*4)|0; | |
//return idx*Math.PI/6; | |
return (idx - 2)*Math.PI/4; | |
//return ((6*Math.random()-3)|0)*Math.PI/6; | |
if(Math.random() > 0.5){ | |
return Math.PI/2; | |
} | |
return -Math.PI/2; | |
} | |
function outside(v) { | |
return Math.abs(v.x) > (w>>1) || Math.abs(v.y) > (h>>1); | |
} | |
// part | |
function part(start, dir, w, life) { | |
this.old = clone(start); | |
this.start = clone(start); | |
this.dir = dir; | |
this.dist = length(this.dir); | |
this.width = w || 60; | |
this.distance = 0; | |
this.max_distance = this.width==1?2: this.width*15; | |
this.life = life; | |
this.update = function(dt) { | |
mov(this.old, this.start); | |
madd(this.start, dt, this.dir); | |
this.distance += this.dist*dt; | |
this.life--; | |
if(this.distance > this.max_distance) { | |
if(Math.random() < 0.5) { | |
this.start = add(this.start, mul(-0.2, this.dir)); | |
this.dir = rot(this.dir, rndAng()); | |
} else { | |
part.add(new part( | |
clone(this.start), | |
mul(0.8, rot(this.dir, rndAng())), | |
Math.max(1,this.width>>1), | |
(this.life*0.6)|0) | |
); | |
} | |
this.distance = 0; | |
} | |
if(outside(this.start) || this.life <= 0) { | |
part.free(this); | |
} | |
} | |
this.render = function(ctx) { | |
ctx.beginPath(); | |
ctx.lineWidth = this.width; | |
var alpha = Math.min(this.width*0.4, 0.8); | |
ctx.strokeStyle = 'rgba(0, 0, 0, ' + alpha + ')'; | |
ctx.lineCap = 'round'; | |
ctx.moveTo(this.old.x, this.old.y); | |
ctx.lineTo(this.start.x, this.start.y); | |
ctx.stroke(); | |
} | |
} | |
part.all = []; | |
part.free = function(p) { | |
part.all[p.index] = null; | |
} | |
part.get_free = function() { | |
for(var i = 0; i < part.all.length; ++i) { | |
if(!part.all[i]) return i; | |
} | |
return null; | |
} | |
part.add = function(p) { | |
if(part.all.length == 1000) { | |
var i = part.get_free(); | |
if(i !== null) { | |
part.all[i] = p; | |
p.index = i; | |
} | |
} else { | |
p.index = part.all.length; | |
part.all.push(p); | |
} | |
} | |
for(var i = 0; i < 10; ++i) { | |
part.add(new part(v2(0, 0), rot(v2(0, 16), rndAng()*3), 25, 800)); | |
} | |
var frame = function(fn) { setTimeout(fn, 16); } | |
function loop() { | |
for(var i = 0; i < part.all.length; ++i) { | |
var p = part.all[i]; | |
if(p) { | |
p.update(1); | |
p.render(ctx); | |
} | |
} | |
frame(loop); | |
} | |
frame(loop); | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment