加法混色と減法混色(2)
/**
* 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();
}
}
}