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

forked from: ドット絵的ななにか

画像読み込んでゴニョゴニョするよ
// forked from soundkitchen's ドット絵的ななにか
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.filters.BlurFilter;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.MouseEvent;
    import flash.events.SecurityErrorEvent;
    import flash.geom.Point;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    [SWF(frameRate=60, width=465, height=465, backgroundColor=0x000000)]

    /**
     *  画像読み込んでゴニョゴニョするよ
     */
    public class Main extends Sprite
    {
        /**
         *  適当に選んだ Flickr のサムネイル画像の URL
         */
        public static const IMAGE_URL:String = 'http://farm3.static.flickr.com/2320/2056363823_ee69da67b9_s.jpg';

        /**
         *  ぽつぽつの半径
         */
        public static const RADIUS:Number = 3;

        private var parts:Vector.<Particle>;
        private var canvas:Shape;
        private var film:BitmapData;

        /**
         *  コンストラクタ
         */
        public function Main()
        {
            addEventListener(Event.ENTER_FRAME, this.enterFrameHandler);
        }
        
        /**
         *  stage を監視
         *  firefox3@mac対応
         */
        private function enterFrameHandler(event:Event):void
        {
            if (stage.stageWidth && stage.stageHeight)
            {
                removeEventListener(Event.ENTER_FRAME, this.enterFrameHandler);
                
                initialize();
            }
        }

        /**
         *  stage のサイズが取得できた時の処理
         */
        private function initialize():void
        {
            //  stage の設定
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.MEDIUM;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            //  色々書き込むためのキャンバス用 Shape
            canvas = new Shape();

            //  最終的に書き込まれるフィルム用 BitmapData
            film = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0);
            addChild(new Bitmap(film));

            //  画像読み込み処理へ
            loadImage();
        }

        /**
         *  画像を読み込む処理
         */
        private function loadImage():void
        {
            var req:URLRequest,
                loader:Loader,
                ctx:LoaderContext;

            req = new URLRequest(IMAGE_URL);
            ctx = new LoaderContext(true);
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadFailure);
            loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loadFailure);
            loader.load(req, ctx);
        }

        /**
         *  画像読み込み完了時の処理
         */
        private function loadComplete(evt:Event):void
        {
            var i:uint,
                w:uint, h:uint,
                centerX:Number, centerY:Number,
                angle:Number,
                p:Particle,
                bmd:BitmapData;

            centerX = stage.stageWidth / 2;
            centerY = stage.stageHeight / 2;

            //  元画像を取ってくる
            bmd = Bitmap(evt.target.content).bitmapData;

            //  必要な数だけパーティクルを作る
            parts = new Vector.<Particle>(bmd.width * bmd.height, true);
            for (i=0; i<parts.length; i++)
            {
                //  縦・横のポジションを計算
                w = Math.floor(i % bmd.width);
                h = Math.floor(i / bmd.width);

                //  パーティクル作るよ。
                p = new Particle();
                //  色を元画像から取ってくる。
                p.color = bmd.getPixel(w, h);
                //  目標地点をセット
                p.end = new Point(w * RADIUS * 2 + RADIUS,
                                  h * RADIUS * 2 + RADIUS);
                //  スタート地点をセット
                angle = Math.random() * Math.PI * 2;
                p.start = new Point(Math.cos(angle) * 500 + centerX,
                                    Math.sin(angle) * 500 + centerY);
                //  FIXME: ココがダサい
                //  スタート地点を現在地にコピー
                p.x = p.start.x;
                p.y = p.start.y;

                //  配列に特攻む
                parts[i] = p;
            }
            //  元画像を破棄
            bmd.dispose();

            //  イベント群を登録
            addEventListener(Event.ENTER_FRAME, step);
            stage.addEventListener(MouseEvent.CLICK, toggleReverse);
        }

        /**
         *  毎フレームでパーティクルを動かす
         */
        private function step(evt:Event):void
        {
            var i:uint,
                l:uint,
                p:Particle,
                g:Graphics;

            l = parts.length;
            g = canvas.graphics;

            g.clear();
            for (i=0; i<l; i++)
            {
                p = parts[i];
                p.update(stage.mouseX, stage.mouseY);

                g.beginFill(p.color);
                g.drawCircle(p.x, p.y, RADIUS * p.scale);
                g.endFill();
            }

            film.lock();
            film.fillRect(film.rect, 0);
            film.draw(canvas);
            film.applyFilter(film, film.rect, new Point(0, 0), new BlurFilter(5, 5));
            film.unlock();
        }

        /**
         *  stage をクリックされた時の処理
         */
        private function toggleReverse(evt:MouseEvent):void
        {
            //  reverse なフラグを逆にする
            Particle.reverse = !Particle.reverse;
        }

        /**
         *  読み込みエラー時の処理
         */
        private function loadFailure(evt:Event):void
        {
            //  トレースするだけ
            trace(evt);
        }
    }
}

import flash.geom.Point;

class Particle
{
    private const SPRING_CONST:Number = 0.11;
    private const FRICTION:Number = 0.89;

    public static var reverse:Boolean = false;

    public var start:Point;
    public var end:Point;
    public var color:uint;
    public var x:Number;
    public var y:Number;
    
    public var v:Number = 0;
    public var tmpScale:Number = 0;
    public var scale:Number = 0;

    public function Particle()
    {
    
    }

    public function update(mouseX:Number, mouseY:Number):void
    {
        var target:Point,
            delta:Point;

        target = reverse ? start : end;
        delta = target.subtract(new Point(x, y));

        x += delta.x * .1;
        y += delta.y * .1;

        var dx:Number = mouseX - x;
        var dy:Number = mouseY - y;
	var distance:Number = Math.sqrt(dx * dx + dy * dy);
	if (distance < 100)
	{
            tmpScale = 1 + (10 / (distance / 10 + 1));
	}
	else
	{
            tmpScale = 1;
	}
	
	this.applyScale();
    }
    
    private function applyScale():void
    {
        var scaledis:Number = tmpScale - scale;
        var a:Number = SPRING_CONST * scaledis;
        v += a;
        v *= FRICTION;
	
        scale += v;
        scale += v;
    }
}