forked from: FireFlyEffect (refactored)
/**
* Copyright nitoyon ( http://wonderfl.net/user/nitoyon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4Zl3
*/
package
{
import flash.display.BitmapData;
import flash.system.LoaderContext;
import flash.display.LoaderInfo;
import flash.display.Loader;
import flash.display.StageScaleMode;
import flash.display.Sprite;
import flash.display.BlendMode;
import flash.display.Bitmap;
import flash.net.URLRequest;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.events.Event;
import flash.filters.BlurFilter;
import com.bit101.components.ColorChooser;
import com.bit101.components.RadioButton;
import com.bit101.components.HUISlider;
import com.bit101.components.CheckBox;
import com.bit101.components.Panel;
import org.libspark.thread.EnterFrameThreadExecutor;
import org.libspark.thread.Thread;
[SWF(backgroundColor="#000000", frameRate=60)]
public class FireFlyEffect extends Sprite
{
private var sSpeed : HUISlider;
private var sLife : HUISlider;
private var sFrequency : HUISlider;
private var sStrength : HUISlider;
private var colorChooser : ColorChooser;
private var canvas : Sprite;
private var sourceBMP:Bitmap;
private var effectBmd:BitmapData;
private var white:Array;
public function FireFlyEffect()
{
// take a capture after 10 sec
Wonderfl.capture_delay( 10 );
stage.scaleMode = StageScaleMode.NO_SCALE;
Thread.initialize(new EnterFrameThreadExecutor());
addChild(new Bitmap(new BitmapData(460, 460, false, 0)));
var loader:Loader = addChild(new Loader()) as Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, start);
loader.load(new URLRequest("http://www.imajuk.com/GillSans.png"), new LoaderContext(true));
}
private function start(event : Event) : void
{
//=================================
// the Bitmap as resource
//=================================
sourceBMP =
LoaderInfo(event.target).loader.content as Bitmap;
sourceBMP.x = 80;
sourceBMP.y = 50;
sourceBMP.transform.colorTransform =
new ColorTransform(1, 1, 1, 1, 0, 0, -20, 0);
//=================================
// UI
//=================================
var panel:Panel = new Panel(this, 50, 330);
panel.setSize(200, 100);
panel.color = 0;
//=================================
// slider for strength
//=================================
sStrength = new HUISlider(panel, 0, 0, "strength");
sStrength.setSliderParams(1, 10, 10);
//=================================
// slider for speed
//=================================
sSpeed = new HUISlider(panel, 0, 11, "speed");
sSpeed.setSliderParams(1, 50, 5);
//=================================
// slider for life time of effect
//=================================
sLife = new HUISlider(panel, 0, 22, "life");
sLife.setSliderParams(1, 200, 3);
//=================================
// slider for frequency of effect
//=================================
sFrequency = new HUISlider(panel, 0, 33, "frequency");
sFrequency.setSliderParams(0.01, 1, 1);
//=================================
// color chooser
//=================================
colorChooser =
new ColorChooser(panel, 280, 5, 0x00FF00);
//=================================
// toggle text visible
//=================================
var checkBox:CheckBox =
new CheckBox(
panel, 280, 30, "hide text",
function():void
{
sourceBMP.alpha = checkBox.selected ? 0 : 1;
}
);
//=================================
// preset : TWINKLE
//=================================
new RadioButton(
panel, 200, 5, "TWINKLE", true,
function(event:Event):void
{
sStrength.value = 10;
sSpeed.value = 5;
sLife.value = 3;
sFrequency.value = .7;
canvas.filters = [new BlurFilter(2, 2, 4)];
}
);
//=================================
// preset : SOFT
//=================================
new RadioButton(
panel, 200, 16, "SOFT", false,
function(event:Event):void
{
sStrength.value = 5;
sSpeed.value = 1;
sLife.value = 160;
sFrequency.value = .05;
canvas.filters = [new BlurFilter(4, 4, 4)];
}
);
//=================================
// preset : HARD
//=================================
new RadioButton(
panel, 200, 27, "HARD", false,
function(event:Event):void
{
sStrength.value = 4;
sSpeed.value = 30;
sLife.value = 70;
sFrequency.value = .4;
canvas.filters = [new BlurFilter(2, 2, 4)];
}
);
//=================================
// canvas
//=================================
effectBmd = new BitmapData(sourceBMP.width, sourceBMP.height, true, 0);
canvas = addChild(new Sprite()) as Sprite;
for (var i:int = 0; i < 4; i++) {
canvas.addChild(new Bitmap(effectBmd)).blendMode = BlendMode.ADD;
}
canvas.filters = [new BlurFilter(2, 2, 4)];
canvas.blendMode = BlendMode.ADD;
canvas.x = sourceBMP.x;
canvas.y = sourceBMP.y;
prepare();
addEventListener("enterFrame", enterFrameHandler);
}
private function prepare() : void
{
white = [];
for(var x:int = 0; x < sourceBMP.bitmapData.width; x++)
{
for(var y:int = 0; y < sourceBMP.bitmapData.height; y++)
{
if(sourceBMP.bitmapData.getPixel32(x, y) > 0)
white.push(new Point(x,y));
}
}
}
private function enterFrameHandler(event:Event):void
{
var refreshRate:Number = Math.min(.3, sSpeed.value / 50);
var colorTransform:ColorTransform = new ColorTransform(1, 1, 1, 1, 0, 0, 0, -refreshRate * 0xFF);
effectBmd.lock();
effectBmd.colorTransform(effectBmd.rect, colorTransform);
if (Math.random() <= sFrequency.value) {
new FireFlyLightThread(
sourceBMP.bitmapData,
effectBmd,
sStrength.value,
sSpeed.value,
colorChooser.value | 0xFF000000,
sLife.value,
white[Math.floor(white.length * Math.random())] as Point).start();
}
effectBmd.unlock();
}
}
}
import flash.display.BitmapData;
import flash.geom.Point;
import org.libspark.thread.Thread;
class FireFlyLightThread extends Thread
{
private static var white : Array = [];
private var source : BitmapData;
private var canvas : BitmapData;
private var pos : Point;
private var vec : Number;
private var life : int;
private var speed : int;
private var color : uint;
private var cnt : int = 0;
private var stength : int;
public function FireFlyLightThread(
source : BitmapData,
canvas : BitmapData,
strength : int = 2,
speed : int = 1,
color : uint = 0xFFFFFFFF,
life:int = 100,
pos:Point = null
)
{
super();
this.canvas = canvas;
this.source = source;
this.vec = Math.PI;
this.color = color;
this.speed = speed;
this.stength = strength;
this.life = int(Math.random() * life);
this.pos = pos;
}
override protected function run() : void
{
// ライフがなくなったらそこで終了
if (life-- < 0)
return;
// 2回に1回、drawTwincle() を実行
if (++cnt % 2 == 0)
{
// speed 分だけ移動させる
var sp : int = speed;
while(sp-- > 0)
{
drawTwincle();
}
}
// 次のフレームも run 実行
next(run);
}
private function drawTwincle() : void
{
//ベクトル方向の座標増分
var ax : int = Math.round(Math.cos(vec));
var ay : int = Math.round(Math.sin(vec));
if (ax == 0 && ay == 0)
return;
//移動するつもりの座標
var dx:int = pos.x + ax;
var dy:int = pos.y + ay;
//ピクセルがあれば移動
if (source.getPixel32(dx, dy) > 0)
{
//現在位置を更新
pos.x = dx;
pos.y = dy;
var argb : uint = color;
var a : uint = (argb >> 24) & 0xFF;
var px:int;
var py:int;
var rad2:Number = vec += .2;
// サイズが strength の十字星型を描画する
var s:int = 0;
while(++s <= stength && a > 0x01)
{
var c:int = 0;
while(c++ < 4)
{
px = Math.cos(rad2) * s + pos.x;
py = Math.sin(rad2) * s + pos.y;
canvas.setPixel32(px, py, argb);
rad2 += Math.PI * .5;
}
a = (argb >> 24) & 0xFF;
a *= .8;
argb = (a << 24) | (argb & 0x00FFFFFF);
}
}
else
{
//ピクセルがなければ方向を変える
vec += Math.PI * .25 * ((Math.random() > .5) ? 1 : -1);
}
}
}