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

加法混色と減法混色(2)

Get Adobe Flash player
by Aquioux 14 Sep 2012
/**
 * Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/yuqU
 */

package {
    import a24.tween.Tween24;
    import com.bit101.components.PushButton;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.BlendMode;
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.ConvolutionFilter;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    /**
     * 加法混色と減法混色(2)
     * @author YOSHIDA, Akio (Aquioux)
     * @see http://aquioux.net/blog/?p=2821
     * Picture 「フリー写真素材 Futta.NET」 http://www.futta.net/
     */
    [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#808080")]
    
    public class Main2 extends Sprite {
        // 各チャンネル BitmapData
        // RGB
        private var rBmd_:BitmapData;    // RED
        private var gBmd_:BitmapData;    // GREEN
        private var bBmd_:BitmapData;    // BLUE
        // CMY
        private var cBmd_:BitmapData;    // CYAN
        private var mBmd_:BitmapData;    // MAGENTA
        private var yBmd_:BitmapData;    // YELLOW
        
        // 各チャンネル Bitmap
        private var ch1Bm_:Bitmap;        // チャンネル1 BitmapData のコンテナ(RED / CYAN)
        private var ch2Bm_:Bitmap;        // チャンネル2 BitmapData のコンテナ(GREEN / MAGENTA)
        private var ch3Bm_:Bitmap;        // チャンネル3 BitmapData のコンテナ(BLUE / YELLOW)

        // 表示オブジェクト
        private var ch1Sp_:Sprite;        // チャンネル1 Bitmap のコンテナ(RED / CYAN)
        private var ch2Sp_:Sprite;        // チャンネル2 Bitmap のコンテナ(GREEN / MAGENTA)
        private var ch3Sp_:Sprite;        // チャンネル3 Bitmap のコンテナ(BLUE / YELLOW)
        private var backGroundSp_:Sprite;    // ステージを覆う Sprite(ステージ全体の背景色を変えるためのもの)
        
        private var chSps_:Array;        // Tween24 用

        // ボタン
        private var modeButton_:PushButton;    // モード切り替えボタン
        
        // ブレンドモード
        private const RGB_BLEND_MODE:String = BlendMode.ADD;
        private const CMY_BLEND_MODE:String = BlendMode.SUBTRACT;
        private var currentBlendMode_:String;
        
        // ステージ塗りつぶし色
        private const RGB_BACKGROUND_COLOR:uint = 0x000000;
        private const CMY_BACKGROUND_COLOR:uint = 0xFFFFFF;
        private var currentFillColor_:uint;
        
        // PushButton のラベル
        private const RGB_LABEL:String = "RGB";
        private const CMY_LABEL:String = "CMY";
        private var currentLabel_:String;
        
        // モード切り替えトグル
        private var toggle_:Boolean;


        // コンストラクタ
        public function Main2() {
            var url:String = "http://assets.wonderfl.net/images/related_images/2/23/23a3/23a3798d426e7239bbb74a0a023039474d2d2b58"
            var loader:Loader = new Loader();
            loader.load(new URLRequest(url), new LoaderContext(true));
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
        }

        private function completeHandler(event:Event):void {
            // ソースイメージ
            var sourceBmd:BitmapData = event.target.loader.content.bitmapData;

            // 画像処理用パラメータ生成
            var w:int = sourceBmd.width;
            var h:int = sourceBmd.height;
            var rect:Rectangle = new Rectangle(0, 0, w, h);
            var zero:Point = new Point(0, 0);
            
            // ソース色反転(CMY用)
            var negativeBmd:BitmapData = sourceBmd.clone();
            negativeBmd.applyFilter(negativeBmd, rect, zero, new ConvolutionFilter(1, 1, [ -1], 1, 255));
            
            // 各チャンネルの BitmapData 生成
            rBmd_ = new BitmapData(w, h, false, 0x000000);
            gBmd_ = rBmd_.clone();
            bBmd_ = rBmd_.clone();
            cBmd_ = rBmd_.clone();
            mBmd_ = rBmd_.clone();
            yBmd_ = rBmd_.clone();

            // copyChannel 実行
            rBmd_.copyChannel(sourceBmd,   rect, zero, BitmapDataChannel.RED,   BitmapDataChannel.RED);
            gBmd_.copyChannel(sourceBmd,   rect, zero, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
            bBmd_.copyChannel(sourceBmd,   rect, zero, BitmapDataChannel.BLUE,  BitmapDataChannel.BLUE);
            cBmd_.copyChannel(negativeBmd, rect, zero, BitmapDataChannel.RED,   BitmapDataChannel.RED);
            mBmd_.copyChannel(negativeBmd, rect, zero, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
            yBmd_.copyChannel(negativeBmd, rect, zero, BitmapDataChannel.BLUE,  BitmapDataChannel.BLUE);
            
            // Bitmap 生成
            ch1Bm_ = new Bitmap();
            ch2Bm_ = new Bitmap();
            ch3Bm_ = new Bitmap();
            
            // ステージを覆う Sprite 生成
            backGroundSp_ = new Sprite();
            addChild(backGroundSp_);
            
            // 各チャンネル Sprite 生成(各チャンネル Bitmap をドラッグできるように wrap する)
            ch1Sp_ = new Sprite();
            ch2Sp_ = new Sprite();
            ch3Sp_ = new Sprite();
            chSps_ = [ch1Sp_, ch2Sp_, ch3Sp_];

            ch1Sp_.buttonMode = true;
            ch2Sp_.buttonMode = true;
            ch3Sp_.buttonMode = true;
            ch1Sp_.addChild(ch1Bm_);
            ch2Sp_.addChild(ch2Bm_);
            ch3Sp_.addChild(ch3Bm_);
            
            // 各チャンネル Sprite 初期配置
            var sw:int = stage.stageWidth;
            var sh:int = stage.stageHeight;
            ch1Sp_.x = Math.random() * (sw - w - 20) + 10;
            ch1Sp_.y = Math.random() * (sh - h - 20) + 10;
            ch2Sp_.x = Math.random() * (sw - w - 20) + 10;
            ch2Sp_.y = Math.random() * (sh - h - 20) + 10;
            ch3Sp_.x = Math.random() * (sw - w - 20) + 10;
            ch3Sp_.y = Math.random() * (sh - h - 20) + 10;
            addChild(ch1Sp_);
            addChild(ch2Sp_);
            addChild(ch3Sp_);
            
            // 各チャンネル Sprite にイベントリスナー登録
            ch1Sp_.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            ch2Sp_.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            ch3Sp_.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            ch1Sp_.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            ch2Sp_.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            ch3Sp_.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            
            // ボタン
            var buttonWidth:int = 50;
            // モード切り替えボタン
            modeButton_ = new PushButton(this, 0, 0, "",  modeButtonHandler);
            // 各チャンネルコンテナ位置一致ボタン
            var matchButton:PushButton = new PushButton(this, 0, 0, "match", matchButtonHandler);
            modeButton_.width = buttonWidth;
            matchButton.width = buttonWidth;
            matchButton.x = buttonWidth;
            
            // 初回表示
            modeButtonHandler(null);
        }
        
        // モード切り替えボタンのイベントハンドラ
        private function modeButtonHandler(event:MouseEvent):void {
            // トグルによる判別
            if (toggle_) {
                // CMY
                currentBlendMode_ = CMY_BLEND_MODE;
                currentFillColor_ = CMY_BACKGROUND_COLOR;
                currentLabel_     = CMY_LABEL;
                ch1Bm_.bitmapData = cBmd_;
                ch2Bm_.bitmapData = mBmd_;
                ch3Bm_.bitmapData = yBmd_;
            } else {
                // RGB
                currentBlendMode_ = RGB_BLEND_MODE;
                currentFillColor_ = RGB_BACKGROUND_COLOR;
                currentLabel_     = RGB_LABEL;
                ch1Bm_.bitmapData = rBmd_;
                ch2Bm_.bitmapData = gBmd_;
                ch3Bm_.bitmapData = bBmd_;
            }
            // トグルをスイッチ
            toggle_ = !toggle_;
            // モード切り替え処理実行
            update();
        }
        // モード切り替え処理
        private function update():void {
            // 各チャンネル Bitmap
            ch1Bm_.blendMode = currentBlendMode_;
            ch2Bm_.blendMode = currentBlendMode_;
            ch3Bm_.blendMode = currentBlendMode_;
            
            // ステージを覆う Sprite
            var g:Graphics = backGroundSp_.graphics;
            g.beginFill(currentFillColor_);
            g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            g.endFill();
            
            // モード切り替えボタンのラベル
            modeButton_.label = currentLabel_;
        }

        // 各チャンネルコンテナ位置一致ボタンのイベントハンドラ
        private function matchButtonHandler(event:MouseEvent):void {
            Tween24.tween(chSps_, 1.5, Tween24.ease.ElasticOut).x(133).y(133).play();
        }
        
        // 各チャンネル Sprite のマウスイベントハンドラ
        private function mouseDownHandler(event:MouseEvent):void {
            event.target.startDrag();
        }
        private function mouseUpHandler(e:MouseEvent):void {
            e.target.stopDrag();
        }
    }
}