Beautifl - Flash Gallery

Thumbnail : Fractals @ 24 FPS
Fractals @ 24 FPS
yonatan 2009-09-04 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// forked from yonatan's Tweening Sheep (realtime fractal generator)
// http://en.wikipedia.org/wiki/Iterated_function_system

package  
{
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.utils.*;
    import flash.text.*;
    import flash.ui.Mouse;
    import __AS3__.vec.Vector;
    import gs.TweenMax;
    import gs.easing.*;
    import net.hires.debug.Stats;

    [SWF(backgroundColor = "0x000000", frameRate = "24")]
    public class Main extends Sprite
    {
        public function Main():void 
        {
            Wonderfl.capture_delay( 30 );
            init(stage.stageWidth, stage.stageHeight);
            addChild(view);
            addChild(new Stats());
            addChild( tf = new TextField );
            tf.y = 100;
            tf.width = stage.stageWidth;
            tf.textColor = 0xFFFFFF;
            stage.quality = "low";
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            Mouse.cursor = flash.ui.MouseCursor.BUTTON;
            stage.addEventListener(MouseEvent.CLICK, onClick);
            addEventListener(Event.ENTER_FRAME, onEnter);
        }

        private function onClick(e:MouseEvent):void 
        {
            change();
        }

        private var oldTime:Number = 0;
        private function adjustToFrameRate():void {
            const DAMP:Number = 10;

            tf.text = "Iterations/Frame: " + numIterations;

            // maintain a constant framerate
            var newTime:Number = getTimer();
            var iterPerMs:Number = numIterations / (newTime - oldTime);
            oldTime = newTime;
            numIterations = (numIterations * DAMP + (1000/stage.frameRate) * iterPerMs) / (DAMP+1);
        }

        private function onEnter(e:Event):void 
        {
            transforms[0].rotation += 0.012;
            transforms[1].rotation -= 0.003;
            transforms[2].rotation += 0.005;
            transforms[3].rotation -= 0.007;
            draw();
            adjustToFrameRate();
        }

        private var w: int;
        private var h: int;
        private var mw: int;
        private var mh: int;
        private const SCREEN_SCALE:Number = 150;
        private var view: Bitmap;
        private var bmpData: BitmapData;
        private var buffer: Vector.<uint>;

        private var numIterations:uint = 50000;
        private static const NUM_TRANSFORMS:uint = 4;   
        private var transforms:Vector.<Transform>;

        private var tonedown:ColorTransform;
        private var filter:BlurFilter;

        private var tf:TextField;

        private function init(w: int, h: int):void
        {
            this.w = w;
            mw = w >> 1;
            this.h = h;
            mh = h >> 1;
            bmpData = new BitmapData(w, h, false, 0x00000000);
            stage.fullScreenSourceRect = bmpData.rect;
            view = new Bitmap(bmpData);
            tonedown = new ColorTransform(
                .92,.92,.92,.92,
                -5,-5,-5,-5);
            filter = new BlurFilter(1.5, 1.5, 1);

            // init matrix and color arrays
            transforms = new Vector.<Transform>;
            for( var i:uint = 0; i < NUM_TRANSFORMS; i++ ) {
                transforms.push( new Transform );
            }

            change();
        }
        
        private var curx:Number = 0;
        private var cury:Number = 0;
        private var color:uint = 0xFFFFFF;
        private var topleft:Point = new Point(0,0);

        private function draw(): void
        {
            var b: Vector.<uint> = buffer;

            var bi: uint; // buf idx
            var ti: int;  // transform idx
            
            bmpData.lock();
            b = bmpData.getVector(bmpData.rect);

            var screenx:int, screeny:int;
            var newx:Number;
            var xform:Transform;
            var rnd:Number;

            for( var i:uint = 0; i < numIterations; i++ ) {
                xform = transforms[int(Math.random()*NUM_TRANSFORMS)];

                // It's too bad that Matrix.transformPoint creates a new Point object
                newx    = curx * xform.a + cury * xform.b + xform.tx;
                cury = curx * xform.c + cury * xform.d + xform.ty;
                curx = newx;

                screenx = curx * SCREEN_SCALE + mw;
                screeny = cury * SCREEN_SCALE + mh;

                color = ((color & 0xFEFEFE) + (xform.color & 0xFEFEFE)) >>> 1;
                if( screenx >= 0 && screenx < w && screeny >= 0 && screeny < h )
                {
                    bi = screeny * w + screenx;
                    b[bi] = ((color & 0xFEFEFE) + (b[bi] & 0xFEFEFE)) >>> 1;
                }
            }
            
            bmpData.setVector(bmpData.rect, b);
            bmpData.applyFilter(bmpData, bmpData.rect, topleft, filter);
            bmpData.colorTransform(bmpData.rect, tonedown);
            bmpData.unlock();
        }
        
        private function change(): void
        {
            for( var i:uint = 0; i < NUM_TRANSFORMS; i++ ) {
                TweenMax.to( transforms[i], 3.5, {
                        delay: i/6,
                        ease: Bounce.easeOut,
                        tx: Math.random() * 2 - 1,
                        ty: Math.random() * 2 - 1,
                        scaleX: Math.random() * 0.5 + 0.25,
                        scaleY: Math.random() * 0.5 + 0.25,
                        rotation: transforms[i].rotation + (Math.random() - 0.5) * 2 * Math.PI,
                        hexColors:{color:Math.random()*0xFFFFFF | 0x202020} } );
            }
        }
    }
}

import flash.geom.*;
// ugly tween wrapper
class Transform extends Matrix {
    private var _x:Number = 0;
    private var _y:Number = 0;
    private var _scaleX:Number = 1;
    private var _scaleY:Number = 1;
    private var _rotation:Number = 0;
    public var color:uint = 0xFFFFFF;
    public var probability:Number;

    public function set rotation( angle:Number ):void {
        _rotation = angle;
        update();
    }

    public function set scaleX( value:Number ):void {
        _scaleX = value;
        update();
    }

    public function set scaleY( value:Number ):void {
        _scaleY = value;
        update();
    }

    public function get rotation():Number {
        return _rotation;
    }

    public function get scaleX():Number {
        return _scaleX;
    }

    public function get scaleY():Number {
        return _scaleY;
    }

    private function update():void {
        var tmpty:Number = ty;
        var tmptx:Number = tx;
        identity();
        scale( _scaleX, _scaleY );
        rotate( _rotation );
        ty = tmpty;
        tx = tmptx;
    }
}