forked from: forked from: forked from: Burn(ShaderFilter)
// forked from BTown's forked from: forked from: Burn(ShaderFilter)
// forked from BTown's forked from: Burn(ShaderFilter)
// forked from 2ndyofyyx's Burn(ShaderFilter)
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Shader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.ShaderFilter;
import flash.geom.Matrix;
import flash.geom.Point;
[SWF(width="465", height="465", frameRate="30")]
public class Burn extends Sprite {
private static const W:int = 64;
private static const H:int = 64;
private static const PALETTE_PNG:String = "iVBORw0KGgoAAAANSUhEUgAAAQAAAAABCAYAAAAxWXB3AAABnklEQVR42hXDAWgMAAAAwGd4DMPwGCaTpaXJ1NLKZOnTZGqtL5OlpclkaWky9enLZGlpMrW0Mln6NJksLU2mPq1Mlj5Nppa+TJaWJlPvdnWBQCCQnud8M1zgQhcZdLFLXGqmy1zuCrNc6SpXm+0a17rOkOvd4EZz3ORmt5jrVre53R3utMBd7naPey12nyXu94AHPWTYwx7xqMestMqIxz3hSU9Z62nPeNZznveCjV70kpe9YtSrxrzmdW940zZveds73rXTe3Z53wc+9JFxH/vEpz7zuS8c8KWvfO0bE7512He+94MfTfrJz37xqxN+M+V3f/jTX0772z/+9Z/puRkGzTTLbEPmmGue+RZYaJHFllhqmWHLrbDSiNXWWGud9TbYaJPNRo3ZYqttttthp11222PcXvvsd8BBh0w47IijJh1z3AlTTjrltDPOmp6bYdBMs8w2ZI655plvgYUWWWyJpZYZttwKK41YbY211llvg4022WzUmC222ma7HXbaZbc9xu21z34HHHTIhMOOOGrSMcedMOWkU04742z6PyjtNAJqn82kAAAAAElFTkSuQmCC";
private static const HEATBLUR_PBJ:String = "pQEAAACkCABIZWF0Qmx1cqAMbmFtZXNwYWNlAGpwLnl5eC4ybmR5LnBiawCgDHZlbmRvcgAybmR5b2Z5eXgAoAh2ZXJzaW9uAAEAoQECAAAMX091dENvb3JkAKMABHNyYwChAgQBAA9kc3QAMgAAIAAAAAAyAgCAv4AAADICAEAAAAAAHQIAMQAAEAABAgAxAgAQADADAPECALAAAQAAIAMAAAAyAgCAAAAAADICAEAAAAAAHQIAMQAAEAABAgAxAgAQADADAPECALAAAQAAIAMAAAAyAgCAP4AAADICAEAAAAAAHQIAMQAAEAABAgAxAgAQADADAPECALAAAQAAIAMAAAAyAgCAAAAAADICAEA/gAAAHQIAMQAAEAABAgAxAgAQADADAPECALAAAQAAIAMAAAAyAAAQPn4AAAMAACAAAMAAHQEAgAAAgAAyAgCAP4AAADICAEAAAAAAMgIAIAAAAAAdAQByAgBgAA==";
private static const PALETTE_PBJ:String = "pQEAAACkBwBQYWxldHRloAxuYW1lc3BhY2UAanAueXl4LjJuZHkucGJrAKAMdmVuZG9yADJuZHlvZnl5eACgCHZlcnNpb24AAQChAQIAAAxfT3V0Q29vcmQAowAEc3JjAKMBBHBhbGV0dGUAoQIEAQAPZHN0ADACAPEAABAAHQAAIAIAAAAyAAAQQ4AAAB0CACAAAIAAAwIAIAAAwAAdAgCAAgCAADIAABAAAAAAHQIAQAAAwAAwAwDxAgAQAR0BAPMDABsA";
private var canvas:Shape = new Shape();
private var heat1:BitmapData = new BitmapData(W, H, false, 0x000000);
private var heat2:BitmapData = new BitmapData(W, H, false, 0x000000);
private var buffer:BitmapData = new BitmapData(W, H, false);
private var blurFilter:ShaderFilter;
private var paletteFilter:ShaderFilter;
private var particles:Array = new Array();
private var matrix:Matrix;
public function Burn() {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.loadBytes(new Base64(PALETTE_PNG));
blurFilter = new ShaderFilter(new Shader(new Base64(HEATBLUR_PBJ)));
var root:Sprite = new Sprite();
addChild(root);
root.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
root.addEventListener(Event.ENTER_FRAME, onEnterFrame);
var image:Bitmap = new Bitmap(buffer);
image.scaleX = 465 / W;
image.scaleY = 465 / W;
image.smoothing = true;
root.addChild(image);
matrix = image.transform.matrix;
matrix.invert();
for(var p:int = 0; p < 7; p++) {
particles.push(new Particle(W/2 + Math.random() * 6 - 3, H*3/4 + Math.random() * 6 - 3, 3, Math.random() * 0.375 + 0.375));
}
for(var i:int = 0; i < 6; i++) {
step();
blur();
}
}
private function onLoadComplete(event:Event) : void {
var paletteShader:Shader = new Shader(new Base64(PALETTE_PBJ));
paletteShader.data.palette.input = event.target.loader.content.bitmapData;
paletteFilter = new ShaderFilter(paletteShader);
}
private function onEnterFrame(evt:Event):void {
step();
blur();
buffer.applyFilter(heat1, heat1.rect, new Point(), paletteFilter);
}
private function onMouseDown(evt:MouseEvent):void {
var p:Point = matrix.transformPoint(new Point(evt.localX, evt.localY));
for(var i:int = 0; i < 25; i++) {
particles.push(new Particle(p.x + Math.random() * 6 - 3, p.y + Math.random() * 6 - 3, 3, Math.random() * 0.375 + 0.375));
}
}
private function step():void {
var g:Graphics = canvas.graphics;
g.clear();
for each(var p:Particle in particles) {
p.step();
if(p.isAlive()) {
g.lineStyle(1, 0xff0000, 3 * p.age / Math.sqrt(p.vx * p.vx + p.vy * p.vy));
g.moveTo(p.x - p.vx, p.y - p.vy);
g.lineTo(p.x, p.y);
}
}
while(particles.length > 0 && !particles[0].isAlive()) {
particles.shift();
}
heat1.draw(canvas);
}
private function blur():void {
heat2.applyFilter(heat1, heat1.rect, new Point(), blurFilter);
var tmp:BitmapData = heat1;
heat1 = heat2;
heat2 = tmp;
}
}
}
class Particle {
public var x:Number, y:Number, vx:Number, vy:Number;
public var age:Number;
private static const G:Number = 0.005;
public function Particle(x0:Number, y0:Number, r:Number, age0:Number) {
x = x0;
y = y0;
var s:Number = (Math.random() + 1) / 3 * Math.PI;
var t:Number = (Math.random() + 0.5) * Math.PI;
vx = r * Math.cos(s) * Math.sin(t);
vy = r * Math.sin(s) * Math.cos(t);
age = age0;
}
public function step() : void {
x += vx;
y += vy;
vy += G;
vx *= (31 / 32);
vy *= (31 / 32);
age -= (1 / 64);
}
public function isAlive() : Boolean {
return age > 0;
}
}
import flash.utils.ByteArray;
class Base64 extends ByteArray {
private static const BASE64:Array = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,0,0,0,0,0];
public function Base64(str:String) {
var n:int, j:int;
for(var i:int = 0; i < str.length && str.charAt(i) != "="; i++) {
j = (j << 6) | BASE64[str.charCodeAt(i)];
n += 6;
while(n >= 8) {
writeByte((j >> (n -= 8)) & 0xFF);
}
}
position = 0;
}
}