blendModeとはなんぞや?

と思って調べたところ、簡単に言ってしまえば、PhotoShopにあるレイヤーの乗算とかスクリーンみたいなもん。


ようは色んな効果・・ブラーとかグローフィルターなどいくつか設定したときにblindModeすると混ざり合って、自然な感じというか・・合成というか・・・いろんな効果が生み出せそうです。


使用方法は


var bl:BlurFilter = new BlurFilter(8, 8, 1);
var gf:GlowFilter = new GlowFilter(color,0.2, 80,80,8, 2);
obj.filters = [bl, gf];
obj.blendMode = BlendMode.ADD;  //ADDは加算


そのほかにもBlendMode.NORMALなど様々ものがある。


詳しくは「http://hakuhin.hp.infoseek.co.jp/main/as3/display_obj.html#DISPLAY_OBJ_09 」に載っています。



下記のコードは前回と似ているがオブジェクト(Sprite)自体にブラーとグローフィルターをかけて加算している


package {
import caurina.transitions.*;
//
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.Point;
import flash.utils.Timer;
/**
* ...
* @author $(DefaultUser)
*/
public class BitMapTest3 extends Sprite{
//
private var bmd:BitmapData;
private var bm:Bitmap;
//object
private var canvas:Sprite;
private var obj:Sprite;
//
//
public function BitMapTest3() {
//init
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.LOW;
//
init();
}
//初期設定
private function init():void {
canvas = new Sprite();
addChild(canvas);
//create bitmapdata
bmd = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00000000);
bm = new Bitmap(bmd);
addChild(bm);
//
//start timer
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
//
addEventListener(Event.ENTER_FRAME, LoopAciton);
}

private function LoopAciton(e:Event):void {
bmd.draw(canvas);
//bmd.scroll(0, 4);
bmd.applyFilter(bmd, bmd.rect, new Point(0, 0), new BlurFilter(8, 8, 4));
}

private function timerHandler(e:TimerEvent):void {
//create object
obj = new Sprite();
var color:uint = Math.random() * 0xFFFFFF;
obj.graphics.beginFill(color);
var radius:int = Math.random() * 20 + 20;
obj.graphics.drawCircle(radius / 2, radius / 2, radius);
obj.graphics.endFill();
//
obj.x = Math.random() * stage.stageWidth;
obj.y = Math.random() * stage.stageHeight;
canvas.addChild(obj);
//
//blurfilter
var bl:BlurFilter = new BlurFilter(8, 8, 1);
var gf:GlowFilter = new GlowFilter(color,0.2, 80,80,8, 2);
obj.filters = [bl, gf];
obj.blendMode = BlendMode.ADD;
//
var targetX:Number = obj.x + Math.random() * 600 - 300;
var targetY:Number = obj.y + Math.random() * 600 - 300;
var Rotation:Number = Math.random() * 720;
var targetTime:Number = Math.random() * 2 + 2;
//
//
Tweener.addTween(obj, {
x:targetX,
y:targetY,
rotation:Rotation,
alpha:0,
time:targetTime,
transition:"easeOutSine",
onCompleteParams:[obj],
onComplete:remoeObj
} );
}
//移動完了後削除をする
private function remoeObj(target:Sprite):void {
canvas.removeChild(target);
}

}

}

Bitmapのdrawを使用した方法をメモ


自分が思ったなるほど・・と思った点


■ENTER_FRAME内でのdraw


BitmapDataを作成してそこにステージ自体・・[this]をdrawさせるとステージに表示されているオブジェクトが描画される。

またENTER_FRAMEでループさせているのでオブジェクトを移動させている間もdrawされるのでちょいと幻想的な描画ができる。


■scrollを使用するとdrawで描画されたものが移動する


scrollを調べてみたところ、「x」および「y」パラメーターは「int型」でx軸とy軸のスクロール量をピクセルで指定する。

とのことでした。


package {
import caurina.transitions.*;
import flash.filters.BlurFilter;
//
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Point;
import flash.events.*;
import flash.display.*;

/**
* ...
* @author $(DefaultUser)
*/
public class BitMapTest2 extends MovieClip{
//
public var start_btn:MovieClip;
//
//Bitmap関連
private var bmd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x000000);
private var bm:Bitmap = new Bitmap(bmd);
private var bf:BlurFilter = new BlurFilter(5, 5, 3);   //ぼかし量を設定
//オブジェクト
private var obj1:cr=new cr();
private var obj2:cr2=new cr2();
private var obj3:cr3=new cr3();
private var obj4:cr4=new cr4();
//---------------------
//コンストラクタ
//---------------------
public function BitMapTest2() {
//
start_btn.addEventListener(MouseEvent.CLICK, doCLick);
start_btn.buttonMode = true;
}

private function doCLick(e:MouseEvent):void {
addChild(bm);
addChild(obj1);
addChild(obj2);
addChild(obj3);
addChild(obj4);
//
obj1.x = stage.stageWidth / 2;
obj1.y = stage.stageHeight / 2;
//
obj2.x = stage.stageWidth / 2;
obj2.y = stage.stageHeight / 2;
//
obj3.x = stage.stageWidth / 2;
obj3.y = stage.stageHeight / 2;
//
obj4.x = stage.stageWidth / 2;
obj4.y = stage.stageHeight / 2;
//

//
addEventListener(Event.ENTER_FRAME, LoopAction);
}

private function LoopAction(e:Event):void {
bmd.draw(this);                         //ステージを描画
bmd.scroll(0,1);                         //y軸に一ピクセルスクロール
bmd.applyFilter(bmd, bmd.rect, new Point(0, 0), bf);   
//
Tweener.addTween(obj1, {
x:mouseX,
y:mouseY,
rotation:Math.random() * 100,
transition:"easeOutExpo",
time:1
} );
Tweener.addTween(obj2, {
x:450-mouseX,
y:mouseY,
rotation:Math.random() * 100,
transition:"easeOutExpo",
time:1
} );
Tweener.addTween(obj3, {
x:mouseY,
y:450-mouseX,
rotation:Math.random() * 100,
transition:"easeOutExpo",
time:1
} );
Tweener.addTween(obj4, {
x:mouseY,
y:mouseX,
rotation:Math.random() * 100,
transition:"easeOutExpo",
time:1
} );
}

}

}


applyFilterを設定しないとオブジェクトがそのまま描画される。今回はぼかしを適用して幻想的な感じなので使用

papervision3Dで作成したオブジェクトにイベントを設定する方法は前回メモったところだけども、そのオブジェクトにブラーフィルタを適用させたいときは「useOwnContainer」プロパティを「true」に変更する


var p:Plane = new Plane(compo, 100, 70, 1, 1);
p.useOwnContainer = true;


しかしこの設定をすると下記のイベントの発動が無くなってしまう。


InteractiveScene3DEvent.OBJECT_CLICK

InteractiveScene3DEvent.OBJECT_DOUBLE_CLICK


特に「OBJECT_CLICK」に関しては結構使用頻度がありそうなだけにショック。


てことでどうすればいいのかネットを探しまくっていたところ、「note.x」さん のブログにて発見。


「papervision3d/view/layer/ViewportLayer.as のコンストラクタに「this.mouseChildren = false」を追加すればオケ。」


と書いてあったので早速チェックしてみました。


//コンストラクタ

public function ViewportLayer(viewport:Viewport3D, do3d:DisplayObject3D, isDynamic:Boolean = false)
{
super();
this.viewport = viewport;
this.displayObject3D = do3d;
this.dynamicLayer = isDynamic;
this.graphicsChannel = this.graphics;

if(isDynamic){
this.filters = do3d.filters;
this.blendMode = do3d.blendMode;
this.alpha = do3d.alpha;
}

if(do3d){
addDisplayObject3D(do3d);
do3d.container = this;
}
this.mouseChildren = false;
init();
}


上記の赤い部分「 this.mouseChildren = false;」の一行を追加するだけで大丈夫でした。


実際試してみたので確かです。


なるほどって思った。