|
HTML5テクニカルノート
EaselJSでインスタンスにマスクをかける
ID: FN1209005 |
Technique: HTML5 and JavaScript |
2012年8月にCreateJS Suiteの新しいバージョンが公開されました。そして、新たなEaselJS 0.5.0にはDisplayObject.maskプロパティが備わり、インスタンスをShapeオブジェクトでマスクできるようになりました。本稿ではこのプロパティを試します。
01 ふたつ重ねた同じ画像のインスタンスの下側にフィルタをかける
まずは、同じ画像が読込まれたBitmapインスタンスをふたつ重ね、その下側のインスタンスにフィルタをかけます。そして、次項で手前のインスタンスをマスクで抜くつもりです。
使うフィルタはふたつです。第1に、ColorMatrixFilterで画像イメージをセピア調に変えます。DisplayObjectインスタンスへのフィルタのかけ方とColorMatrixFilterの操作については、「EaselJSのフィルタColorMatrixFilterでイメージをセピア調に変える」をお読みください。
第2に、BoxBlurFilterで矩形領域にぼかしをかけます。コンストラクタには3つの引数を渡して、ぼかし方が決められます。初めのふたつの引数はぼかし幅で、ピクセルを単位とします。最後の引数はぼかしの品質とされ、処理する回数を1から3までの整数で定めます。
new BoxBlurFilter(ぼかす水平ピクセル数, ぼかす垂直ピクセル数, ぼかし品質)
以下のコード001は、同じ画像が読込まれたBitmapインスタンスをふたつ重ねて、その下側インスタンスにぼかしとセピア調カーラーのフィルタをかけます。基本的な処理の組立ては、前出「EaselJSのフィルタColorMatrixFilterでイメージをセピア調に変える」のコード002と同じです。ただ、Bitmapインスタンスの数がふたつに増えています。そのふたつのインスタンスのBitmap.imageプロパティには、同じ画像イメージ(Imageオブジェクト)が定められていることに注目しておきましょう(第50〜51および第57行目)。
コード001■ふたつ重ねた同じ画像が読込まれたBitmapインスタンスの下側にフィルタをかける
- <script>
- var createjs = window;
- </script>
- <script src="easeljs/utils/UID.js"></script>
- <script src="easeljs/geom/Matrix2D.js"></script>
- <script src="easeljs/geom/Point.js"></script>
- <script src="easeljs/events/MouseEvent.js"></script>
- <script src="easeljs/display/DisplayObject.js"></script>
- <script src="easeljs/display/Container.js"></script>
- <script src="easeljs/display/Stage.js"></script>
- <script src="easeljs/display/Bitmap.js"></script>
- <script src="easeljs/filters/Filter.js"></script>
- <script src="easeljs/filters/BoxBlurFilter.js"></script>
- <script src="easeljs/filters/ColorMatrixFilter.js"></script>
- <script src="easeljs/filters/ColorMatrix.js"></script>
- <script src="preloadjs/AbstractLoader.js"></script>
- <script src="preloadjs/PreloadJS.js"></script>
- <script src="preloadjs/TagLoader.js"></script>
- <script src="preloadjs/XHRLoader.js"></script>
- <script>
- var stage;
- var file = "images/Pen.png";
- var filtersList = [];
- function initialize() {
- var canvasElement = document.getElementById("myCanvas");
- stage = new Stage(canvasElement);
- var colorSepia = [
- 0.393, 0.769, 0.189, 0, 0,
- 0.349, 0.686, 0.168, 0, 0,
- 0.272, 0.534, 0.131, 0, 0,
- 0, 0, 0, 1, 0
- ];
- var loader = new PreloadJS(false);
- loader.onFileLoad = draw;
- loader.center = new Point(canvasElement.width / 2, canvasElement.height / 2);
- loader.loadFile({src:file});
- filtersList.push(new BoxBlurFilter(2, 2, 2));
- filtersList.push(new ColorMatrixFilter(colorSepia));
- }
- function setAppearance(instance, nX, nY) {
- instance.x = nX;
- instance.y = nY;
- stage.addChild(instance);
- }
- function draw(eventObject) {
- var myImage = eventObject.result;
- var center = this.center;
- var centerX = center.x;
- var centerY = center.y;
- setFilter(createBitmap(centerX, centerY, myImage));
- createBitmap(centerX + 20, centerY, myImage);
- stage.update();
- }
- function createBitmap(nX, nY, myImage) {
- var myBitmap = new Bitmap();
- setAppearance(myBitmap, nX - myImage.width / 2, nY - myImage.height / 2);
- myBitmap.image = myImage;
- return myBitmap;
- }
- function setFilter(myBitmap) {
- var myImage = myBitmap.image;
- myBitmap.filters = filtersList;
- myBitmap.cache(0, 0, myImage.width, myImage.height);
- }
- </script>
|
前掲コード001では、下のBitmapインスタンスにフィルタがかかったことを確かめられるように、上のインスタンスは水平位置を少しずらしました(図001)。次項で上のインスタンスをマスクで抜くときには、位置は揃えます。
図001■ふたつ重ねた同じ画像のBitmapインスタンスの下にフィルタがかかった
02 Shapeオブジェクトのマスクでインスタンスを抜く
それでは、前掲コード001に手を加えて、手前のBitmapインスタンスをマスクで抜きます。マスクをかけるには、DisplayObject.maskプロパティに、マスクのかたちで描いたShapeオブジェクトを定めます。
DisplayObjectオブジェクト.mask = Shapeオブジェクト
Shapeオブジェクトに描画しますので、script要素にはShapeとGraphicsのふたつのクラスを読込んでおきます(第12〜13行目)。なお、行番号は後にscript要素全体を掲げるコード002にもとづきます。
- <script src="easeljs/display/Shape.js"></script>
- <script src="easeljs/display/Graphics.js"></script>
|
マスクにするShapeインスタンスは、後で使い回しやすいように変数(myShape)で宣言しておきます(第27行目)。そして、マスクのShapeインスタンスをつくる関数(createShape())は別に定め、AbstractLoader.onFileLoadイベントのハンドラ(draw())から呼出します(第54行目)。関数でつくるShapeは星形にしました(「EaselJSで描いた星形を回す」01「EaselJSで星形を描く」参照)。
このマスクのShapeインスタンスをつくる関数(createShape())の中で、Container.addChild()メソッドが使われていないことにご注目ください。マスクにするインスタンスを見せなくてよい場合には、Stageオブジェクトの表示リストに加えなくてもよいのです。マスクを設定する関数(setMask())は別に定めて、ロードのイベントハンドラ(draw())から呼出しました(第56行目)。
- var myShape;
- function draw(eventObject) {
- myShape = createShape(centerX, centerY, 80);
- setMask(createBitmap(centerX, centerY, myImage), myShape);
- }
- function createShape(nX, nY, radius) {
- var myShape = new Shape();
- var myGraphics = myShape.graphics;
- myGraphics.drawPolyStar(0, 0, radius, 5, 0.6, -90);
- myShape.x = nX;
- myShape.y = nY;
- return myShape;
- }
- function setMask(instance, myShape) {
- instance.mask = myShape;
- }
|
同じ画像のBitmapインスタンスをふたつ重ね、下にはフィルタをかけ、上のインスタンスは星形のマスクで抜いたのが、以下のコード002です。もっとも、それだけではつまらないので、Tickerクラスを用いて(第14および第57行目)、tickイベントのアニメーションでマスクを回しました(第82〜85行目)。Tickerクラスを使ったアニメーションについては、前出「EaselJSで描いた星形を回す」02「EaselJSを使ったスクリプトによるアニメーション」をお読みください。
コード002■ふたつ重ねたBitmapインスタンスの手前側にかけた星形のマスクを回す
- <script>
- var createjs = window;
- </script>
- <script src="easeljs/utils/UID.js"></script>
- <script src="easeljs/geom/Matrix2D.js"></script>
- <script src="easeljs/geom/Point.js"></script>
- <script src="easeljs/events/MouseEvent.js"></script>
- <script src="easeljs/display/DisplayObject.js"></script>
- <script src="easeljs/display/Container.js"></script>
- <script src="easeljs/display/Stage.js"></script>
- <script src="easeljs/display/Bitmap.js"></script>
- <script src="easeljs/display/Shape.js"></script>
- <script src="easeljs/display/Graphics.js"></script>
- <script src="easeljs/utils/Ticker.js"></script>
- <script src="easeljs/filters/Filter.js"></script>
- <script src="easeljs/filters/BoxBlurFilter.js"></script>
- <script src="easeljs/filters/ColorMatrixFilter.js"></script>
- <script src="easeljs/filters/ColorMatrix.js"></script>
- <script src="preloadjs/AbstractLoader.js"></script>
- <script src="preloadjs/PreloadJS.js"></script>
- <script src="preloadjs/TagLoader.js"></script>
- <script src="preloadjs/XHRLoader.js"></script>
- <script>
- var stage;
- var file = "images/Pen.png";
- var filtersList = [];
- var myShape;
- function initialize() {
- var canvasElement = document.getElementById("myCanvas");
- stage = new Stage(canvasElement);
- var colorSepia = [
- 0.393, 0.769, 0.189, 0, 0,
- 0.349, 0.686, 0.168, 0, 0,
- 0.272, 0.534, 0.131, 0, 0,
- 0, 0, 0, 1, 0
- ];
- var loader = new PreloadJS(false);
- loader.onFileLoad = draw;
- loader.center = new Point(canvasElement.width / 2, canvasElement.height / 2);
- loader.loadFile({src:file});
- filtersList.push(new BoxBlurFilter(2, 2, 2));
- filtersList.push(new ColorMatrixFilter(colorSepia));
- }
- function setAppearance(instance, nX, nY) {
- instance.x = nX;
- instance.y = nY;
- stage.addChild(instance);
- }
- function draw(eventObject) {
- var myImage = eventObject.result;
- var center = this.center;
- var centerX = center.x;
- var centerY = center.y;
- myShape = createShape(centerX, centerY, 80);
- setFilter(createBitmap(centerX, centerY, myImage));
- setMask(createBitmap(centerX, centerY, myImage), myShape);
- Ticker.addListener(window);
- stage.update();
- }
- function createBitmap(nX, nY, myImage) {
- var myBitmap = new Bitmap();
- setAppearance(myBitmap, nX - myImage.width / 2, nY - myImage.height / 2);
- myBitmap.image = myImage;
- return myBitmap;
- }
- function setFilter(myBitmap) {
- var myImage = myBitmap.image;
- myBitmap.filters = filtersList;
- myBitmap.cache(0, 0, myImage.width, myImage.height);
- }
- function createShape(nX, nY, radius) {
- var myShape = new Shape();
- var myGraphics = myShape.graphics;
- myGraphics.drawPolyStar(0, 0, radius, 5, 0.6, -90);
- myShape.x = nX;
- myShape.y = nY;
- return myShape;
- }
- function setMask(instance, myShape) {
- instance.mask = myShape;
- }
- function tick() {
- myShape.rotation += 5;
- stage.update();
- }
- </script>
|
これで、フィルタのかかった画像の上で、もと画像を抜いた星形のマスクが回るアニメーションになります(図002)。
図002■フィルタのかかった画像の上でもと画像を抜いたマスクが回る
作成者: 野中文雄
作成日: 2012年9月10日
Copyright ©
2001-2012 Fumio Nonaka. All rights reserved.
|