In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Julia Eyes

<3

Julia Mandelbrot + PixelBender test
Get Adobe Flash player
by lespleen 30 Jun 2011
/**
 * Copyright lespleen ( http://wonderfl.net/user/lespleen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/aFKJ
 */

package 
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Rectangle;
    import flash.geom.Point;
    import flash.utils.*;
    import flash.filters.*
    import flash.events.*
        
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLLoaderDataFormat;
    import flash.system.Security;
    import flash.filters.ShaderFilter;
    import flash.system.LoaderContext;
    
    import net.hires.debug.Stats;
    
    [SWF(width="400", height="400", frameRate="35", backgroundColor="#000000")]
    
    final public class Julia extends Sprite
    {
        
        private var fx:VolumetricPointLight;
          
        public var bmp:Bitmap;
        public var bd:BitmapData;
        
        public var COMPLEX_REAL:Number
        public var threshold:Number
        public var COMPLEX_IM:Number 
        
        public var r:Number 
        public var phase:Number
    
        private var sinLUT:TrigLUT; 
        private var cosLUT:TrigLUT; 
        
        private var W:int = 0
        private var H:int = 0
        
        private var pixels:Vector.<uint>; 
        
        private var pjbLoader:URLLoader;
        
        private var shader:Shader
        private var filter:ShaderFilter;
        
        private const ZERO_POINT:Point = new Point(0,0)
        
        public function Julia()
        {
            super()
            stage ? init() :  addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
        }

       
        private function init():void
        {
           Security.loadPolicyFile("http://www.spleen.noo.name/crossdomain.xml");
           
           pjbLoader = new URLLoader();
           pjbLoader.dataFormat = URLLoaderDataFormat.BINARY;
           pjbLoader.addEventListener(Event.COMPLETE,onLoadPjb,false,0,true);
           pjbLoader.load(new URLRequest("http://www.spleen.noo.name/pbj/FocusingLinearBlur.pbj"))
            
       }

        private function onLoadPjb(e:Event):void
        {
           pjbLoader.removeEventListener(Event.COMPLETE, onLoadPjb)
            
            W = stage.stageWidth
            H = stage.stageHeight
        
            stage.quality = "medium";
            stage.align = "TL";
            stage.scaleMode = "noScale";

            sinLUT = new TrigLUT(3, Math.sin);
            cosLUT = new TrigLUT(3, Math.cos);
                
            shader= new Shader( pjbLoader.data );
            //shader.data["amount"]["value"] = [0.2];
            //shader.data["steps"]["value"] = [10];

            filter = new ShaderFilter( shader )
            
            pixels = new Vector.<uint>(W * H, true);
            
            bd = new BitmapData( W, H, false, 0);
            
            bmp = new Bitmap( bd);
            
            fx = new VolumetricPointLight(800, 600, bmp, [0xc08040, 0x4080c0, 0], [1, 1, 1], [0, 20, 30]);
            addChild( fx );
            
            fx.srcX = W/2
            fx.srcY = H/2
            
            //fx.setViewportSize(W, H);
            fx.startRendering();
            
           // addChild( new Stats())
            
            COMPLEX_REAL = 0;
            COMPLEX_IM = 0;
            
            threshold = 50;
            r =100;
            phase = Math.random() * 2 * Math.PI;
            
            this.addEventListener(Event.ENTER_FRAME, run, false, 0, true);
        }

        private function run(e:Event) : void
        {
             //shader.data.center.value=[ mouseX, mouseY]
             
            r = sinLUT.val(getTimer() / 9173 + phase);
            
            COMPLEX_REAL = r * cosLUT.val( getTimer() / 2830) + (mouseX - 200) / 200;
            COMPLEX_IM = r * sinLUT.val( getTimer() / 1297) +  (mouseY - 200) / 200;;
            
            draw();
        }
        
        private function draw() : void
        {
           
            
            var passion:Number,love:Number
            
            var step:int = 0;
            
            var we:Number,are:Number
          
            bd.lock()
            bd.fillRect( bd.rect, 0xa0000000);
            
            var x:int = 0;
            var y:int = 0;
             
            while (x < W)
            {
                
                y= 0;
                while (y < H)
                {
                    
                    passion = (x - W/2) / 200;
                    love = (y - H/2) / 200;
                    
                    step = 0;
                    
                    while (step< 80)
                    {
                        
                        if (passion * passion + love * love > threshold)
                        {
                              
                            pixels[y*H + x ] = 0xa0 << 24 | (255 * step / 20) << 16 | 0x0 << 8 | 0x0;
                             
                            break;
                        }
                        
                        we = passion * passion - love * love + COMPLEX_REAL;
                        are = ((passion * love)*2) + COMPLEX_IM;
                        
                        passion = we
                        love = are
                        
                        step += 4;
                    }
                    
                    y++;
                }
                
                x++;
            }
            
            bd.setVector(bd.rect, pixels)
            bd.applyFilter( bd, bd.rect, ZERO_POINT, filter)
            bd.unlock()
        }// end function

    }
}







/**
* VolumetricPointLight creates a simple effect container with a gradient emission pattern.
* The gradient's center is automatically moved to the (srcX, srcY) coordinates
* and it's radius is adjusted to the length of the viewport's diagonal, so if you
* set srcX and srcY to the viewport's center then only half of the gradient colors
* will be used.
*
* <p>This should also perform a little better than EffectContainer.</p>
*/

import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;

class EffectContainer extends Sprite {
   
    public var blur:Boolean = false;
    public var colorIntegrity:Boolean = false;
    public var intensity:Number = 4;
    public var passes:uint = 6;
     public var rasterQuality:String = null;
    public var scale:Number = 2;
    public var smoothing:Boolean = true;
     public var srcX:Number;
    public var srcY:Number;

    protected var _blurFilter:BlurFilter = new BlurFilter(2, 2);
    protected var _emission:DisplayObject;
    protected var _occlusion:DisplayObject;
    protected var _ct:ColorTransform = new ColorTransform;
    protected var _halve:ColorTransform = new ColorTransform(0.5, 0.5, 0.5);
    protected var _occlusionLoResBmd:BitmapData;
    protected var _occlusionLoResBmp:Bitmap;
    protected var _baseBmd:BitmapData;
    protected var _bufferBmd:BitmapData;
    protected var _lightBmp:Bitmap = new Bitmap;
    protected var _bufferSize:uint = 0x8000;
    protected var _bufferWidth:uint;
    protected var _bufferHeight:uint;
    protected var _viewportWidth:uint;
    protected var _viewportHeight:uint;
    protected var _mtx:Matrix = new Matrix;

    /**
    * Creates a new effect container.
    *
    * @param width Viewport width in pixels.
    * @param height Viewport height in pixels.
    * @param emission A DisplayObject to which the effect will be applied. This object will be
    * added as a child of the container. When applying the effect the object's filters and color
    * matrix is ignored, if you want to use filters or a color matrix put your content in another
    * object and addChild it to this one instead.
    * @param occlusion An optional occlusion object, handled the same way as the emission object.
    */
    public function EffectContainer(width:uint, height:uint, emission:DisplayObject, occlusion:DisplayObject = null) {
        if(!emission) throw(new Error("emission DisplayObject must not be null."));
        addChild(_emission = emission);
        if(occlusion) addChild(_occlusion = occlusion);
        setViewportSize(width, height);
        _lightBmp.blendMode = BlendMode.ADD;
        addChild(_lightBmp);
        srcX = width / 2;
        srcY = height / 2;
    }

    /**
    * Sets the container's size. This method recreates internal buffers (slow), do not call this on
    * every frame.
    *
    * @param width Viewport width in pixels
    * @param height Viewport height in pixels
    */
    public function setViewportSize(width:uint, height:uint):void {
        _viewportWidth = width;
        _viewportHeight = height;
        scrollRect = new Rectangle(0, 0, width, height);
        _updateBuffers();
    }

    /**
    * Sets the approximate size (in pixels) of the effect's internal buffers. Smaller number means lower
    * quality and better performance. This method recreates internal buffers (slow), do not call this on
    * every frame.
    *
    * @param size Buffer size in pixels
    */
    public function setBufferSize(size:uint):void {
        _bufferSize = size;
        _updateBuffers();
    }

    protected function _updateBuffers():void {
        var aspect:Number = _viewportWidth / _viewportHeight;
        _bufferHeight = Math.max(1, Math.sqrt(_bufferSize / aspect));
        _bufferWidth  = Math.max(1, _bufferHeight * aspect);
        dispose();
        _baseBmd           = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
        _bufferBmd         = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
        _occlusionLoResBmd = new BitmapData(_bufferWidth, _bufferHeight, true, 0);
        _occlusionLoResBmp = new Bitmap(_occlusionLoResBmd);
    }

    /**
    * Render a single frame.
    *
    * @param e In case you want to make this an event listener.
    */
    public function render(e:Event = null):void {
        var savedQuality:String = stage.quality;
        if(rasterQuality) stage.quality = rasterQuality;
        var mul:Number = colorIntegrity ? intensity : intensity/(1<<passes);
        _ct.redMultiplier = _ct.greenMultiplier = _ct.blueMultiplier = mul;
        _drawLoResEmission();
        if(_occlusion) _eraseLoResOcclusion();
        if(rasterQuality) stage.quality = savedQuality;
        var s:Number = 1 + (scale-1) / (1 << passes);
        var tx:Number = srcX/_viewportWidth*_bufferWidth;
        var ty:Number = srcY/_viewportHeight*_bufferHeight;
        _mtx.identity();
        _mtx.translate(-tx, -ty);
        _mtx.scale(s, s);
        _mtx.translate(tx, ty);
        _lightBmp.bitmapData = _applyEffect(_baseBmd, _bufferBmd, _mtx, passes);
        _lightBmp.width = _viewportWidth;
        _lightBmp.height = _viewportHeight;
        _lightBmp.smoothing = smoothing;
    }

    /**
    * Draws a scaled-down emission on _baseBmd.
    */
    protected function _drawLoResEmission():void {
        _copyMatrix(_emission.transform.matrix, _mtx);
        _mtx.scale(_bufferWidth / _viewportWidth, _bufferHeight / _viewportHeight);
        _baseBmd.fillRect(_baseBmd.rect, 0);
        _baseBmd.draw(_emission, _mtx, colorIntegrity ? null : _ct);
    }

    /**
    * Draws a scaled-down occlusion on _occlusionLoResBmd and erases it from _baseBmd.
    */
    protected function _eraseLoResOcclusion():void {
        _occlusionLoResBmd.fillRect(_occlusionLoResBmd.rect, 0);
        _copyMatrix(_occlusion.transform.matrix, _mtx);
        _mtx.scale(_bufferWidth / _viewportWidth, _bufferHeight / _viewportHeight);
        _occlusionLoResBmd.draw(_occlusion, _mtx);
        _baseBmd.draw(_occlusionLoResBmp, null, null, BlendMode.ERASE);
    }

    /**
    * Render the effect on every frame until stopRendering is called.
    */
    public function startRendering():void {
        addEventListener(Event.ENTER_FRAME, render);
    }

    /**
    * Stop rendering on every frame.
    */
    public function stopRendering():void {
        removeEventListener(Event.ENTER_FRAME, render);
    }

    /**
    * Low-level workhorse, applies the lighting effect to a bitmap. This function modifies the src and buffer
    * bitmaps and it's mtx argument.
    *
    * @param src The BitmapData to apply the effect on.
    * @param buffer Another BitmapData object for temporary storage. Must be the same size as src.
    * @param mtx Effect matrix.
    * @param passes Number of passes to make.
    * @return A processed BitmapData object (supllied in either src or buffer) with final effect output.
    */
    protected function _applyEffect(src:BitmapData, buffer:BitmapData, mtx:Matrix, passes:uint):BitmapData {
        var tmp:BitmapData;
        while(passes--) {
            if(colorIntegrity) src.colorTransform(src.rect, _halve);
            buffer.copyPixels(src, src.rect, src.rect.topLeft);
            buffer.draw(src, mtx, null, BlendMode.ADD, null, true);
            mtx.concat(mtx);
            tmp = src; src = buffer; buffer = tmp;
        }
        if(colorIntegrity) src.colorTransform(src.rect, _ct);
        if(blur) src.applyFilter(src, src.rect, src.rect.topLeft, _blurFilter);
        return src;
    }

    /**
    * Dispose of all intermediate buffers. After calling this the EffectContainer object will be unusable.
    */
    public function dispose():void {
        if(_baseBmd) _baseBmd.dispose();
        if(_occlusionLoResBmd) _occlusionLoResBmd.dispose();
        if(_bufferBmd) _bufferBmd.dispose();
        _baseBmd = _occlusionLoResBmd = _bufferBmd = _lightBmp.bitmapData = null;
    }

    protected function _copyMatrix(src:Matrix, dst:Matrix):void {
        dst.a = src.a;
        dst.b = src.b;
        dst.c = src.c;
        dst.d = src.d;
        dst.tx = src.tx;
        dst.ty = src.ty;
    }
}



import flash.display.*;
import flash.events.*;
import flash.geom.*;


class VolumetricPointLight extends EffectContainer {
    protected var _colors:Array;
    protected var _alphas:Array;
    protected var _ratios:Array;
    protected var _gradient:Shape = new Shape;
    protected var _gradientMtx:Matrix = new Matrix;
    protected var _gradientBmp:Bitmap = new Bitmap;
    protected var _lastSrcX:Number;
    protected var _lastSrcY:Number;
    protected var _lastIntensity:Number;
    protected var _lastColorIntegrity:Boolean = false;
    protected var _gradientLoResBmd:BitmapData;
    protected var _gradientLoResDirty:Boolean = true;

    /**
    * Creates a new effect container, with an emission created from the supplied color or gradient.
    * The constructor lets you use a shortcut syntax for creating simple single-color gradients.
    * @example The shortcut syntax:
    * <listing>new VolumetricPointLight(800, 600, occlusion, 0xc08040);</listing>
    * @example is equivalent to:
    * <listing>new VolumetricPointLight(800, 600, occlusion, [0xc08040, 0], [1, 1], [0, 255]);</listing>
    *
    * @param width Viewport width in pixels.
    * @param height Viewport height in pixels.
    * @param occlusion An occlusion object, will be overlayed above the lighting gradient and under the light effect bitmap.
    * @param colorOrGradient Either a gradient colors array, or a uint color value.
    * @param alphas Will only be used if colorOrGradient is an array. This will be passed to beginGradientFill.
    *               If not provided alphas will all be 1.
    * @param ratios Will only be used if colorOrGradient is an array. This will be passed to
    *               beginGradientFill. If colorOrGradient is an Array and ratios aren't provided default
    *               ones will be created automatically.
    */
    public function VolumetricPointLight(width:uint, height:uint, occlusion:DisplayObject, colorOrGradient:*, alphas:Array = null, ratios:Array = null) {
        if(colorOrGradient is Array) {
            _colors = colorOrGradient.concat();
            if(!ratios)    _ratios = colorOrGradient.map(function(item:*, i:int, arr:Array):int { return 0x100*i/(colorOrGradient.length+i-1) });
            if(!alphas) _alphas = _colors.map(function(..._):Number { return 1 });
        } else {
            _colors = [colorOrGradient, 0];
            _ratios = [0, 255];
        }
        super(width, height, _gradientBmp, occlusion);
        if(!occlusion) throw(new Error("An occlusion DisplayObject must be provided."));
        if(!(colorOrGradient is Array || colorOrGradient is uint)) throw(new Error("colorOrGradient must be either an Array or a uint."));
    }

    protected function _drawGradient():void {
        var size:Number = 2 * Math.sqrt(_viewportWidth*_viewportWidth + _viewportHeight*_viewportHeight);
        _gradientMtx.createGradientBox(size, size, 0, -size/2 + srcX, -size/2 + srcY);
        _gradient.graphics.clear();
        _gradient.graphics.beginGradientFill(GradientType.RADIAL, _colors, _alphas, _ratios, _gradientMtx);
        _gradient.graphics.drawRect(0, 0, _viewportWidth, _viewportHeight);
        _gradient.graphics.endFill();
        if(_gradientBmp.bitmapData) _gradientBmp.bitmapData.dispose();
        _gradientBmp.bitmapData = new BitmapData(_viewportWidth, _viewportHeight, true, 0);
        _gradientBmp.bitmapData.draw(_gradient);
    }

    /**
    * Updates the lo-res gradient bitmap if neccesary and copies it to _baseBmd.
    */
    override protected function _drawLoResEmission():void {
        if(_gradientLoResDirty) {
            super._drawLoResEmission();
            _gradientLoResBmd.copyPixels(_baseBmd, _baseBmd.rect, _baseBmd.rect.topLeft);
            _gradientLoResDirty = false;
        } else {
            _baseBmd.copyPixels(_gradientLoResBmd, _baseBmd.rect, _baseBmd.rect.topLeft);
        }
    }

    /** @inheritDoc */
    override protected function _updateBuffers():void {
        super._updateBuffers();
        _gradientLoResBmd = new BitmapData(_bufferWidth, _bufferHeight, false, 0);
        _gradientLoResDirty = true;
    }

    /** @inheritDoc */
    override public function setViewportSize(width:uint, height:uint):void {
        super.setViewportSize(width, height);
        _drawGradient();
        _gradientLoResDirty = true;
    }

    /** @inheritDoc */
    override public function render(e:Event = null):void {
        var srcChanged:Boolean = _lastSrcX != srcX || _lastSrcY != srcY;
        if(srcChanged) _drawGradient();
        _gradientLoResDirty ||= srcChanged;
        _gradientLoResDirty ||= (!colorIntegrity && (_lastIntensity != intensity));
        _gradientLoResDirty ||= (_lastColorIntegrity != colorIntegrity);
        _lastSrcX = srcX;
        _lastSrcY = srcY;
        _lastIntensity = intensity;
        _lastColorIntegrity = colorIntegrity;
        super.render(e);
    }
}


 /**
 *   A lookup table for trig values (e.g. sine, cosine) to improve on the
 *   performance of the static functions found in the Math class
 *   @author Jackson Dunstan
 */
 class TrigLUT
 {
        /** 2 * PI, the number of radians in a circle*/
        public static const TWO_PI:Number = 2.0 * Math.PI;
 
        /** The static TWO_PI cached as a non-static field*/
        private const TWO_PI:Number = TrigLUT.TWO_PI;
 
        /** Table of trig function values*/
        public var table:Vector.<Number>;
 
        /** 10^decimals of precision*/
        public var pow:Number;
 
        /**
        *   Make the look up table
        *   @param numDigits Number of digits places of precision
        *   @param mathFunc Math function to call to generate stored values.
        *                   Must be valid on [0,2pi).
        *   @throws Error If mathFunc is null or invalid on [0,2pi)
        */
        public function TrigLUT(numDigits:uint, mathFunc:Function)
        {
            var pow:Number = this.pow = Math.pow(10, numDigits);
            var round:Number = 1.0 / pow;
            var len:uint = 1 + this.TWO_PI*pow;
            var table:Vector.<Number> = this.table = new Vector.<Number>(len);
 
            var theta:Number = 0;
            for (var i:uint = 0; i < len; ++i)
            {
                table[i] = mathFunc(theta);
                theta += round;
            }
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of
        *   @return The value of the given number of radians
        */
        public function val(radians:Number): Number
        {
            return radians >= 0
                ? this.table[int((radians%this.TWO_PI)*this.pow)]
                : this.table[int((TWO_PI+radians%this.TWO_PI)*this.pow)];
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of. Must be positive.
        *   @return The sine of the given number of radians
        *   @throws RangeError If radians is not positive
        */
        public function valPositive(radians:Number): Number
        {
            return this.table[int((radians%this.TWO_PI)*this.pow)];
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of. Must be on (-2pi,2pi).
        *   @return The value of the given number of radians
        *   @throws RangeError If radians is not on (-2pi,2pi)
        */
        public function valNormalized(radians:Number): Number
        {
            return radians >= 0
                ? this.table[int(radians*this.pow)]
                : this.table[int((this.TWO_PI+radians)*this.pow)];
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of. Must be on [0,2pi).
        *   @return The value of the given number of radians
        *   @throws RangeError If radians is not on [0,2pi)
        */
        public function valNormalizedPositive(radians:Number): Number
        {
            return this.table[int(radians*this.pow)];
        }
}