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

Asymmetric Spiral Kaleidoscope

角度の黄金比分割とか 出展 - Nature by Number http://www.etereaestudios.com/movies/nbyn_movies/nbyn_mov_youtube.htm
Greetings from a Canadian novice to all my friends in Japan!
/**
 * Copyright brenten ( http://wonderfl.net/user/brenten )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/tiXT
 */

// forked from keno42's のんびり眺める用
// forked from keno42's ひまわりっぽいやつ
// 角度の黄金比分割とか 出展 - Nature by Number http://www.etereaestudios.com/movies/nbyn_movies/nbyn_mov_youtube.htm
// Greetings from a Canadian novice to all my friends in Japan!
package 
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.filters.*;
    import flash.utils.*;
    import net.hires.debug.Stats;
    import flash.ui.Keyboard;
    
    public class Kaleidoscope extends Sprite
    {
        private var MAX_NUM:int = 1800;
        private var num:int = MAX_NUM;
        private var gv:Number = 0;
        private var ga:Number = 0;
        private var angle:Number = 0;
        private var firstP:Particle = new Particle();
        private var lastP:Particle = firstP;
        private var bmpData:BitmapData = new BitmapData(465, 465, false, 0x0);
        private var timer:Timer = new Timer(3300);
        private var _mode:Boolean = true;
        private var _stats:Stats;

        public function Kaleidoscope()
        {
            this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            addChild(new Bitmap(bmpData));
            shoot(firstP, angle);
            timer.addEventListener(TimerEvent.TIMER, onTimer);
            stage.addEventListener(MouseEvent.CLICK, onClick);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKey);
            timer.start();
        }

        private function onKey(event:KeyboardEvent):void {
            if (event.keyCode == Keyboard.SPACE) {
                if (_stats == null)
                {
                    _stats = new Stats();
                    this.stage.addChild(_stats);
                } else
                {
                    this.stage.removeChild(_stats);
                    this._stats = null;
                }
            }
        }

        private function onClick(e:MouseEvent):void
        {
            randomRefresh(e.localX, e.localY);
        }

        private function onTimer(e:TimerEvent):void
        {
            randomRefresh();
        }

        private function randomRefresh(mouseX:uint=0x0, mouseY:uint=0x0):void
        {
            // Toggle mode with every refresh
            this._mode = !_mode;
            if (num != 0)
                 return;
             var tempNum:int = MAX_NUM;
             var p:Particle = firstP;
             var angleDiff:Number = Math.random() * Math.PI * 2;
             var rBase:int = Math.random() * 0xFF;
             var gBase:int = Math.random() * 0xFF;
             var bBase:int = Math.random() * 0xFF;
             var rGoal:int = Math.random() * 0xFF;
             var gGoal:int = Math.random() * 0xFF;
             var bGoal:int = Math.random() * 0xFF;

             angle = 0;
             do
             {
                 tempNum--;
                 angle += angleDiff;
                 if (mouseX > 0x0)
                 {
                        p.x = mouseX;
                }
                if (mouseY > 0x0)
                {
                        p.y = mouseY;
                }
                p.toX = 232 + Math.sqrt(tempNum) * Math.cos(angle) / (MAX_NUM / 9000);
                p.toY = 232 + Math.sqrt(tempNum) * Math.sin(angle) / (MAX_NUM / 9000);
                p.color = Math.floor(rBase + ((rGoal - rBase) * tempNum / MAX_NUM)) 
                        << 16 | Math.floor(gBase + ((gGoal - gBase) * tempNum / MAX_NUM)) 
                        << 8 | Math.floor(bBase + ((bGoal - bBase) * tempNum / MAX_NUM));
            } while (p = p.next);
        }

        private function onEnterFrame(e:Event):void
        {
            var p:Particle = firstP;
            bmpData.lock();
            do
            {
                p.update(this._mode);
                bmpData.setPixel(p.x, p.y, p.color);
            } while (p = p.next)
            bmpData.applyFilter(bmpData, bmpData.rect, new Point(), new BlurFilter(2, 2));
            bmpData.unlock();
            if (num > 0)
            {
                for (var i:int = 0; i < gv; i++)
                {
                    num--;
                    var temp:Particle = new Particle();
                    angle += Math.PI * 137.5077 / 180;
                    shoot(temp, angle);
                    lastP.next = temp;
                    lastP = temp;
                    if (num == 0)
                        break;
                }
                gv += ga;
                ga += 0.02;
            }
        }

        private function shoot(p:Particle, angle:Number):void
        {
            p.x = 232;
            p.y = 232;
            p.toX = 232 + Math.sqrt(num) * Math.cos(angle) / (MAX_NUM / 9000);
            p.toY = 232 + Math.sqrt(num) * Math.sin(angle) / (MAX_NUM / 9000);
            p.color = (0xCC + Math.ceil(0x33 - 0x33 * num / MAX_NUM)) 
                    << 16 | (0x88 + Math.ceil(0x77 - 0x77 * num / MAX_NUM)) 
                    << 8 | (Math.ceil(0x44 * num / MAX_NUM));
        }
    }
}

final class Particle
{
    public var x:Number;
    public var y:Number;
    public var toX:Number;
    public var toY:Number;
    public var color:uint;
    public var next:Particle;

    public function update(mode:Boolean=true):void
    {
        if (mode) {
            x += 0.3 * (toX - x);
            y += 0.1 * (toY - y);
        } else {
            x += 0.1 * (toX - x);
            y += 0.3 * (toY - y);
        }
        if (color == uint.MAX_VALUE) {
            color = 0x0;
        } else if (color % 2 == 0) {
            color = color^2;
        } else {
            color = color/2;
        }
    }
}