flash on 2013-10-25
// rough draft inspired by http://9gag.com/gag/aEwgE6x
// forks are welcome :)
package
{
import flash.display.Sprite;
[SWF(backgroundColor="#000000")]
public class fireworX extends Sprite
{
public var time:Number = 1, rs:Vector.<Number> = new <Number> [
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(),
Math.random(), Math.random(), Math.random(), Math.random(), Math.random(),
Math.random(), Math.random(), Math.random(), Math.random(), Math.random()
];
public function fireworX()
{
addEventListener ("enterFrame", loop);
}
public function loop (...da_hoop):void
{
time -= 0.01; if (time < 0) {
time = 1;
for (var i:int = 0; i < rs.length; i++) {
rs[i] = Math.random();
}
}
var sw:Number = stage.stageWidth;
var sh:Number = stage.stageHeight;
// G for gravity
var gt:Number = 0.2 * sh * time;
var r0x:Number = (0.5 + 0.25 * (rs[0] - rs[3])) * sw;
var r0y:Number = (0.5 + 0.25 * (rs[4] - rs[6])) * sh;
graphics.clear();
for (i = 0; i < rs.length; i++) {
var a:int = (i + 2) % rs.length;
var b:int = (i + 5) % rs.length;
var c:int = (i + 7) % rs.length;
var d:int = (i + 9) % rs.length;
var rix:Number = r0x + 0.5 * (rs[a] - rs[b]) * sw;
var riy:Number = r0y + 0.5 * (rs[c] - rs[d]) * sh;
// A for bezier Anchor
var rax:Number = 0.5 * (r0x + rix);
var ray:Number = 0.5 * (r0y + riy) - 0.4 * sh * (rs[c] + 0.5);
// trail
var t2:Number = time * 0.9;
var t1:Number = t2 - 0.2 * Math.sqrt(t2); if (t1 < 0) t1 = 0;
var N:int = 10;
var A:Number = Math.exp(-time) * Math.sqrt(time);
for (var j:int = 0; j < N; j++) {
var t:Number = 1.0 * j / N;
var tj:Number = t1 + (t2 - t1) * t;
graphics.beginFill(0xBB9900 + 256 * int (42 * rs[j % rs.length]), 5 * A - 2);
graphics.drawCircle(f(tj, r0x, rax, rix), f(tj, r0y, ray, riy) + gt,
6 * A * (1 - (t - 0.5)*(t - 0.5)*4 * rs[j % rs.length] ));
}
// endpoints
var e:Number = Math.max (0, 1 - (time - 0.7) * (time - 0.7) * 4);
graphics.beginFill(0xAABBFF);
graphics.drawCircle(f(time, r0x, rax, rix), f(time, r0y, ray, riy) + gt, 2 * rs[d] * e);
}
}
public function f(t:Number, p0:Number, p1:Number, p2:Number):Number {
// this should have been parabola, but bezier is simpler :P
return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;
}
}
}