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

DetectPixels

//////////////////////////////////////////////////////////////////////////////
[AS3.0] DetectPixelsクラスに挑戦! (3)
http://www.project-nya.jp/modules/weblog/details.php?blog_id=1137
//////////////////////////////////////////////////////////////////////////////
/**
 * Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uUga
 */

////////////////////////////////////////////////////////////////////////////////
// [AS3.0] DetectPixelsクラスに挑戦! (3)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=1137
////////////////////////////////////////////////////////////////////////////////

package {

    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.geom.Rectangle;
    import flash.geom.Point;
    import flash.events.MouseEvent;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import frocessing.color.ColorHSV;

    [SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]

    public class Main extends Sprite {
        private var noise:PerlinNoise;
        private var perlin:Bitmap;
        private var distortion:DistortImage;
        private var detection:DetectPixels;
        private var bitmapDataList:Array;
        private var canvas:Sprite;
        private var layerList:Array;
        private static var layers:uint = 10;
        private static var bHeight:uint = 5;
        private var colorList:Array;
        private var rect:Rectangle;
        private static var accuracy:uint = 2;
        private var threshold:uint = 0xFF000000;
        private var noiseBtn:Btn;
        private var mapBtn:Btn;

        public function Main() {
            Wonderfl.capture_delay(8);
            init();
        }

        private function init():void {
            rect = new Rectangle(0, 0, 300, 200);
            noise = new PerlinNoise(rect, 60, 4, 0);
            noise.colorize({r: 1.5, g: 1.5, b: 1.5}, {r: -0x66, g: -0x66, b: -0x66});
            perlin = new Bitmap(noise);
            addChild(perlin);
            perlin.x = 82;
            perlin.y = 10;
            var base:Shape = new Shape();
            addChild(base);
            base.x = 82;
            base.y = 270;
            base.graphics.beginFill(0x000000);
            base.graphics.moveTo(0, 0);
            base.graphics.lineTo(300, 0);
            base.graphics.lineTo(450, 150);
            base.graphics.lineTo(-150, 150);
            base.graphics.endFill();
            canvas = new Sprite();
            addChild(canvas);
            canvas.x = 82;
            canvas.y = 270;
            detection = new DetectPixels(accuracy);
            distortion = new DistortImage(rect.width, rect.height, 5, 5);
            bitmapDataList = new Array();
            layerList = new Array();
            var hsv:ColorHSV = new ColorHSV(60, 1, 1);
            colorList = new Array();
            for (var n:uint = 0; n < layers; n++) {
                var bitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);
                bitmapDataList.push(bitmapData);
                var layer:Shape = new Shape();
                canvas.addChild(layer);
                layer.y = - bHeight*(n+1);
                layerList.push(layer);
                hsv.h = 80 - 20/layers*(n+1);
                hsv.v = 0.2 + 0.8/layers*(n+1);
                var color:uint = 0xFF << 24 | hsv.value;
                colorList.push(color);
            }
            noiseBtn = new Btn();
            noiseBtn.x = 192;
            noiseBtn.y = 445;
            addChild(noiseBtn);
            noiseBtn.init({id: 0, label: "noise"});
            noiseBtn.addEventListener(MouseEvent.CLICK, create, false, 0, true);
            mapBtn = new Btn();
            mapBtn.x = 272;
            mapBtn.y = 445;
            addChild(mapBtn);
            mapBtn.init({id: 1, label: "map"});
            mapBtn.addEventListener(MouseEvent.CLICK, createMap, false, 0, true);
        }
        private function create(evt:MouseEvent):void {
            noise.create(60, 4, 0);
            noise.colorize({r: 1.5, g: 1.5, b: 1.5}, {r: -0x66, g: -0x66, b: -0x66});
        }
        private function createMap(evt:MouseEvent):void {
            noiseBtn.enabled = false;
            mapBtn.clicked = true;
            clear();
            var timer:Timer = new Timer(100, layers);
            timer.addEventListener(TimerEvent.TIMER, createLayer, false, 0, true);
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, complete, false, 0, true);
            timer.start();
        }
        private function createLayer(evt:TimerEvent):void {
            var id:uint = evt.target.currentCount - 1;
            distort(id);
            detectPixels(id);
        }
        private function complete(evt:TimerEvent):void {
            evt.target.removeEventListener(TimerEvent.TIMER, createLayer);
            evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, complete);
            noiseBtn.enabled = true;
            mapBtn.clicked = false;
        }
        private function distort(id:uint):void {
            var layer:Shape = layerList[id];
            var bitmapData:BitmapData = bitmapDataList[id];
            var p1:Point = new Point(0, 0);
            var p2:Point = new Point(300, 0);
            var p3:Point = new Point(450, 150);
            var p4:Point = new Point(-150, 150);
            distortion.setTransform(layer.graphics, bitmapData, p1, p2, p3, p4);
        }
        private function detectPixels(id:uint):void {
            var bitmapData:BitmapData = bitmapDataList[id];
            bitmapData.lock();
            bitmapData.fillRect(rect, 0x00000000);
            detection.search(noise, rect, threshold);
            var map:Array = detection.pixels();
            var hex:uint = uint(0xFF/layers*(id+1));
            threshold = 0xFF << 24 | hex << 16 | hex << 8 | hex;
            var color:uint = colorList[id];
            for (var n:uint = 0; n < map.length; n++) {
                var area:Rectangle = new Rectangle(map[n].x, map[n].y, accuracy, accuracy);
                bitmapData.fillRect(area, color);
            }
            bitmapData.unlock();
        }
        private function clear():void {
            for (var n:uint = 0; n < layers; n++) {
                var layer:Shape = layerList[n];
                layer.graphics.clear();
            }
            threshold = 0xFF000000;
        }

    }

}


//////////////////////////////////////////////////
// DistortImageクラス
//////////////////////////////////////////////////

import flash.display.BitmapData;
import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Point;
    
class DistortImage {
    protected var _sMat:Matrix, _tMat:Matrix;
    protected var _xMin:Number, _xMax:Number, _yMin:Number, _yMax:Number;
    protected var _hseg:uint, _vseg:uint;
    protected var _hsLen:Number, _vsLen:Number;
    protected var _p:Array;
    protected var _tri:Array;
    protected var _w:Number, _h:Number;
    public var smoothing:Boolean = true;

    public function DistortImage   (w:Number, h:Number, hseg:uint=2, vseg:uint=2):void {
        _w = w;
        _h = h;
        _vseg = vseg;
        _hseg = hseg;
        __init();
    }

    protected function __init():void {
        _p = new Array();
        _tri = new Array();
        var ix: Number;
        var iy: Number;
        var w2: Number = _w / 2;
        var h2: Number = _h / 2;
        _xMin = _yMin = 0;
        _xMax = _w; _yMax = _h;
        _hsLen = _w / ( _hseg + 1 );
        _vsLen = _h / ( _vseg + 1 );
        var x: Number, y: Number;
        for ( ix = 0 ; ix <_vseg + 2 ; ix++ ){
            for ( iy = 0 ; iy <_hseg + 2 ; iy++ ){
                x = ix * _hsLen;
                y = iy * _vsLen;
                _p.push( { x: x, y: y, sx: x, sy: y } );
            }
        }
        for ( ix = 0 ; ix <_vseg + 1 ; ix++ ){
            for ( iy = 0 ; iy <_hseg + 1 ; iy++ ){
                _tri.push([ _p[ iy + ix * ( _hseg + 2 ) ] , _p[ iy + ix * ( _hseg + 2 ) + 1 ] , _p[ iy + ( ix + 1 ) * ( _hseg + 2 ) ] ] );
                _tri.push([ _p[ iy + ( ix + 1 ) * ( _hseg + 2 ) + 1 ] , _p[ iy + ( ix + 1 ) * ( _hseg + 2 ) ] , _p[ iy + ix * ( _hseg + 2 ) + 1 ] ] );
            }
        }
    }
    public function setTransform(graphics:Graphics, bmd:BitmapData, tl:Point, tr:Point, br:Point, bl:Point):void {
        var dx30:Number = bl.x - tl.x;
        var dy30:Number = bl.y - tl.y;
        var dx21:Number = br.x - tr.x;
        var dy21:Number = br.y - tr.y;
        var l:Number = _p.length;
        while( --l> -1 ){
            var point:Object = _p[ l ];
            var gx:Number = ( point.x - _xMin ) / _w;
            var gy:Number = ( point.y - _yMin ) / _h;
            var bx:Number = tl.x + gy * ( dx30 );
            var by:Number = tl.y + gy * ( dy30 );
            point.sx = bx + gx * ( ( tr.x + gy * ( dx21 ) ) - bx );
            point.sy = by + gx * ( ( tr.y + gy * ( dy21 ) ) - by );
        }
        __render(graphics, bmd);
    }
    protected function __render(graphics:Graphics, bmd:BitmapData):void {
        var t: Number;
        var vertices: Array;
        var p0:Object, p1:Object, p2:Object;
        var a:Array;
        _sMat = new Matrix();
        _tMat = new Matrix();
        var l:Number = _tri.length;
        while( --l> -1 ){
            a = _tri[ l ];
            p0 = a[0];
            p1 = a[1];
            p2 = a[2];
            var x0: Number = p0.sx;
            var y0: Number = p0.sy;
            var x1: Number = p1.sx;
            var y1: Number = p1.sy;
            var x2: Number = p2.sx;
            var y2: Number = p2.sy;
            var u0: Number = p0.x;
            var v0: Number = p0.y;
            var u1: Number = p1.x;
            var v1: Number = p1.y;
            var u2: Number = p2.x;
            var v2: Number = p2.y;
            _tMat.tx = u0;
            _tMat.ty = v0;
            _tMat.a = ( u1 - u0 ) / _w;
            _tMat.b = ( v1 - v0 ) / _w;
            _tMat.c = ( u2 - u0 ) / _h;
            _tMat.d = ( v2 - v0 ) / _h;
            _sMat.a = ( x1 - x0 ) / _w;
            _sMat.b = ( y1 - y0 ) / _w;
            _sMat.c = ( x2 - x0 ) / _h;
            _sMat.d = ( y2 - y0 ) / _h;
            _sMat.tx = x0;
            _sMat.ty = y0;
            _tMat.invert();
            _tMat.concat( _sMat );
            graphics.beginBitmapFill( bmd, _tMat, false, smoothing );
            graphics.moveTo( x0, y0 );
            graphics.lineTo( x1, y1 );
            graphics.lineTo( x2, y2 );
            graphics.endFill();
        }
    }
    
}


//////////////////////////////////////////////////
// DetectPixelsクラス
//////////////////////////////////////////////////

import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.Matrix;
import flash.display.IBitmapDrawable;

class DetectPixels {
    private var bd:IBitmapDrawable;
    private var rect:Rectangle;
    private var map:BitmapData;
    private var mapList:Array;
    private var accuracy:uint;
    private var threshold:uint = 0x80FFFFFF;

    public function DetectPixels(a:uint = 1) {
        accuracy = a;
    }

    public function search(t:IBitmapDrawable, r:Rectangle, th:uint = 0x80FFFFFF):void {
        bd = t;
        rect = r;
        threshold = th;
        var w:uint = rect.width/accuracy;
        var h:uint = rect.height/accuracy;
        detect(w, h);
    }
    private function detect(w:uint, h:uint):void {
        map = new BitmapData(w, h, true, 0x00000000);
        var matrix:Matrix = new Matrix();
        matrix.translate(-rect.x, -rect.y);
        matrix.scale(1/accuracy, 1/accuracy);
        map.lock();
        map.draw(bd, matrix);
        map.unlock();
        mapList = new Array();
        for (var x:uint = 0; x < w; x++) {
            for (var y:uint = 0; y < h; y++) {
                var color:uint = map.getPixel32(x, y);
                if (color >= threshold) {
                    var px:int = x*accuracy + rect.x;
                    var py:int = y*accuracy + rect.y;
                    var point:Point = new Point(px, py);
                    mapList.push(point);
                }
            }
        }
    }
    public function pixels():Array {
        return mapList;
    }

}


//////////////////////////////////////////////////
// PerlinNoiseクラス
//////////////////////////////////////////////////

import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.geom.ColorTransform;

class PerlinNoise extends BitmapData {
    private var source:BitmapData;
    private var base:uint;
    private var octaves:uint;
    private var seed:uint;
    private static var point:Point = new Point();
    private var offsets:Array = [point, point];
    private var color:ColorTransform;
    private var multiplier:Object = {r: 1, g: 1, b: 1};
    private var offset:Object = {r: 0x00, g: 0x00, b: 0x00};

    public function PerlinNoise(rect:Rectangle, b:uint = 20, o:uint = 2, s:uint = 1) {
        super(rect.width, rect.height, false, 0xFF000000);
        source = new BitmapData(rect.width, rect.height, false, 0xFF000000);
        create(b, o, s);
    }

    public function create(b:uint, o:uint, s:uint):void {
        base = b;
        octaves = o;
        seed = s;
        if (seed == 0) seed = Math.floor(Math.random()*1000);
        lock();
        source.perlinNoise(base, base, octaves, seed, false, true, 0, true, offsets);
        draw(source);
        unlock();
    }
    public function colorize(m:Object, o:Object):void {
        multiplier = m;
        offset = o;
        color = new ColorTransform(multiplier.r, multiplier.g, multiplier.b, 1, offset.r, offset.g, offset.b, 0);
        lock();
        draw(source, null, color);
        unlock();
    }

}


//////////////////////////////////////////////////
// Btnクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;

class Btn extends Sprite {
    public var id:uint;
    private var shade:Shape;
    private var bottom:Shape;
    private var light:Shape;
    private var base:Shape;
    private var txt:TextField;
    private var label:String = "";
    private static var fontType:String = "_ゴシック";
    private var _width:uint = 60;
    private static var _height:uint = 20;
    private static var corner:uint = 5;
    private var type:uint = 1;
    private static var bColor:uint = 0xFFFFFF;
    private static var sColor:uint = 0x000000;
    private static var upColor:uint = 0x666666;
    private static var overColor:uint = 0x333333;
    private static var offColor:uint = 0x999999;
    private static var gColor:uint = 0x0099FF;
    private var blueGlow:GlowFilter;
    private var shadeGlow:GlowFilter;
    private var _clicked:Boolean = false;
    private var _enabled:Boolean = true;

    public function Btn() {
    }

    public function init(option:Object):void {
        if (option.id != undefined) id = option.id;
        if (option.label != undefined) label = option.label;
        if (option.width != undefined) _width = option.width;
        if (option.type != undefined) type = option.type;
        draw();
    }
    private function draw():void {
        switch (type) {
        case 1 :
            bColor = 0xFFFFFF;
            sColor = 0x000000;
            upColor = 0x666666;
            overColor = 0x333333;
            offColor = 0x999999;
            break;
        case 2 :
            bColor = 0x000000;
            sColor = 0xFFFFFF;
            upColor = 0x666666;
            overColor = 0x999999;
            offColor = 0x333333;
            break;
        }
        blueGlow = new GlowFilter(gColor, 0.6, 5, 5, 2, 3, false, true);
        shadeGlow = new GlowFilter(sColor, 0.3, 4, 4, 2, 3, false, true);
        shade = new Shape();
        bottom = new Shape();
        light = new Shape();
        base = new Shape();
        txt = new TextField();
        addChild(shade);
        addChild(bottom);
        addChild(light);
        addChild(base);
        addChild(txt);
        createBase(shade, _width, _height, corner, sColor);
        shade.filters = [shadeGlow];
        createBase(bottom, _width, _height, corner, sColor, 0.3);
        createBase(light, _width, _height, corner, gColor);
        light.filters = [blueGlow];
        createBase(base, _width, _height, corner, bColor);
        txt.x = -_width*0.5;
        txt.y = -_height*0.5;
        txt.width = _width;
        txt.height = _height - 1;
        txt.type = TextFieldType.DYNAMIC;
        txt.selectable = false;
        //txt.embedFonts = true;
        //txt.antiAliasType = AntiAliasType.ADVANCED;
        var tf:TextFormat = new TextFormat();
        tf.font = fontType;
        tf.size = 12;
        tf.align = TextFormatAlign.CENTER;
        txt.defaultTextFormat = tf;
        txt.text = label;
        enabled = true;
        mouseChildren = false;
    }
    private function rollOver(evt:MouseEvent):void {
        _over();
    }
    private function rollOut(evt:MouseEvent):void {
        _up();
    }
    private function press(evt:MouseEvent):void {
        _down();
    }
    private function release(evt:MouseEvent):void {
        _up();
    }
    private function click(evt:MouseEvent):void {
    }
    private function _up():void {
        txt.y = -_height*0.5;
        txt.textColor = upColor;
        base.y = -1;
        light.visible = false;
        light.y = -1;
    }
    private function _over():void {
        txt.y = -_height*0.5;
        txt.textColor = overColor;
        base.y = -1;
        light.visible = true;
        light.y = -1;
    }
    private function _down():void {
        txt.y = -_height*0.5 + 1;
        txt.textColor = overColor;
        base.y = 0;
        light.visible = true;
        light.y = 0;
    }
    private function _off():void {
        txt.y = -_height*0.5 + 1;
        txt.textColor = offColor;
        base.y = 0;
        light.visible = false;
        light.y = 0;
    }
    public function get clicked():Boolean {
        return _clicked;
    }
    public function set clicked(param:Boolean):void {
        _clicked = param;
        enabled = !_clicked;
        if (_clicked) {
            _down();
        } else {
            _up();
        }
    }
    public function get enabled():Boolean {
        return _enabled;
    }
    public function set enabled(param:Boolean):void {
        _enabled = param;
        buttonMode = _enabled;
        mouseEnabled = _enabled;
        useHandCursor = _enabled;
        if (_enabled) {
            _up();
            addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true);
            addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true);
            addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
            addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
            addEventListener(MouseEvent.CLICK, click, false, 0, true);
        } else {
            _off();
            removeEventListener(MouseEvent.MOUSE_OVER, rollOver);
            removeEventListener(MouseEvent.MOUSE_OUT, rollOut);
            removeEventListener(MouseEvent.MOUSE_DOWN, press);
            removeEventListener(MouseEvent.MOUSE_UP, release);
            removeEventListener(MouseEvent.CLICK, click);
        }
    }
    private function createBase(target:Shape, w:uint, h:uint, c:uint, color:uint, alpha:Number = 1):void {
        target.graphics.beginFill(color, alpha);
        target.graphics.drawRoundRect(-w*0.5, -h*0.5, w, h, c*2);
        target.graphics.endFill();
    }

}