/**
* Copyright 0xABCDEF ( http://wonderfl.net/user/0xABCDEF )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lZM9
*/
// forked from xoul's 30,000 Particles
// forked from xoul's Particle
package
{
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.ColorTransform;
import flash.display.Shape;
import flash.geom.Point;
import flash.filters.BlurFilter;
import flash.display.Sprite;
public class Main extends Sprite
{
private const NUM_PARTICLES : int = 50000;
private const SPEED : Number = 1;
private const MAX_POWER : Number = 100;
private const STAGE_WIDTH : Number = stage.stageWidth;
private const STAGE_HEIGHT : Number = stage.stageHeight;
private var _canvas : BitmapData;
//private var _pixels : Vector.<Pixel>;
private var first:Pixel;
private var _alphaTransform : ColorTransform;
private var _blurFilter : BlurFilter;
private var _zeroPoint : Point;
private var PI:Number = Math.PI;
private var sqrt:Function = Math.sqrt;
private var rand:Function = Math.random;
private var cos:Function = Math.cos;
private var sin:Function = Math.sin;
private function createPixel( curr:Pixel = null ):Pixel
{
var pixel : Pixel = new Pixel;
pixel.x = rand() * STAGE_WIDTH;
pixel.y = rand() * STAGE_HEIGHT;
pixel.dx = 0;
pixel.dy = 0;
pixel.lastX = pixel.x;
pixel.lastY = pixel.y;
pixel.color = 0xFFFFFF;
if( curr ) curr.next = pixel;
return pixel;
}
public function Main()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
_canvas = new BitmapData( STAGE_WIDTH, STAGE_HEIGHT, false, 0 );
addChild( new Bitmap( _canvas ) );
//_pixels = new Vector.<Pixel>( NUM_PARTICLES, true );
first = createPixel();
var pixel:Pixel = createPixel( first );
for( var i : int = 2; i < NUM_PARTICLES; ++i )
{
pixel = createPixel( pixel );
}
_alphaTransform = new ColorTransform( 1, 1, 1, .9 );
_blurFilter = new BlurFilter;
_zeroPoint = new Point;
addEventListener( Event.ENTER_FRAME, onEnterFrame );
stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown );
}
private function onEnterFrame( e : Event ) : void
{
//_canvas.lock();
_canvas.applyFilter( _canvas, _canvas.rect, _zeroPoint, _blurFilter );
_canvas.colorTransform( _canvas.rect, _alphaTransform );
var d : Number;
var dx:Number, dy:Number;
var mx : Number = mouseX;
var my : Number = mouseY;
var pixel:Pixel = first;
while( ( pixel = pixel.next ) != null )
{
pixel.lastX = pixel.x;
pixel.lastY = pixel.y;
dx = pixel.x - mx;
dy = pixel.y - my;
d = sqrt( dx * dx + dy * dy );
pixel.dx -= SPEED * dx / d;
pixel.dy -= SPEED * dy / d;
pixel.x += pixel.dx;
pixel.y += pixel.dy;
pixel.dx *= .95;
pixel.dy *= .95;
efla( pixel.lastX, pixel.lastY, pixel.x, pixel.y, pixel.color );
}
//canvas.applyFilter( canvas, canvas.rect, new Point, blurFilter );
//_canvas.unlock();
}
private function onMouseDown( e : MouseEvent ) : void
{
var randAngle : Number;
var randPower : Number;
var pixel:Pixel = first;
while( ( pixel = pixel.next ) != null )
{
randAngle = rand() * ( PI << 1 );
randPower = rand() * MAX_POWER - ( MAX_POWER >> 1 );
pixel.dx = randPower * cos( randAngle );
pixel.dy = randPower * sin( randAngle );
}
}
// Extremely Fast Line Algorithm : http://wonderfl.net/c/A69m
private function efla(x:int, y:int, x2:int, y2:int, color:uint):void {
var shortLen:int = y2 - y;
var longLen:int = x2 - x;
if (!longLen) if (!shortLen) return;
var i:int, id:int, inc:int;
var multDiff:Number;
var bmd:BitmapData = _canvas;
bmd.lock();
// TODO: check for this above, swap x/y/len and optimize loops to ++ and -- (operators twice as fast, still only 2 loops)
if ((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31)) {
if (shortLen < 0) {
inc = -1;
id = -shortLen % 4;
} else {
inc = 1;
id = shortLen % 4;
}
multDiff = !shortLen ? longLen : longLen / shortLen;
if (id) {
bmd.setPixel32(x, y, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
}
}
}
while (i != shortLen) {
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
}
} else {
if (longLen < 0) {
inc = -1;
id = -longLen % 4;
} else {
inc = 1;
id = longLen % 4;
}
multDiff = !longLen ? shortLen : shortLen / longLen;
if (id) {
bmd.setPixel32(x, y, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
}
}
}
while (i != longLen) {
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
}
}
bmd.unlock();
}
private function drawLine( startX : Number, startY : Number, endX : Number, endY : Number, color : Number ) : void
{
var dx : Number = endX - startX;
var dy : Number = endY - startY;
var a : Number;
var b : Number;
var tmp : Number;
var len : Number;
var i : int;
if( getAbs( dx ) > getAbs( dy ) )
{
a = dy / dx;
b = startY;
if( startX > endX )
{
tmp = startX;
startX = endX;
endX = tmp;
b = endY;
}
len = endX - startX;
for( i = 0; i < len; ++i )
{
_canvas.setPixel( i + startX, i * a + b, color );
}
}
else
{
a = dx / dy;
b = startX;
if( startY > endY )
{
tmp = startY;
startY = endY;
endY = tmp;
b = endX;
}
len = endY - startY;
for( i = 0; i < len; ++i )
{
_canvas.setPixel( i * a + b, i + startY, color );
}
}
}
private function getAbs( x : Number ) : Number
{
return x < 0 ? -x : x;
}
}
}
class Pixel
{
public var next:Pixel;
public var x : Number;
public var y : Number;
public var dx : Number;
public var dy : Number;
public var lastX : Number;
public var lastY : Number;
public var color : uint;
}