Help us understand the problem. What is going on with this article?

CreateJS 1.0.0のStageGLでStageを置き替える

More than 1 year has passed since last update.

EaselJS 1.0.0に、新たなWebGLへの対応としてStageGLクラスが導入されました(「CreateJS: StageGL ー EaselJSのWebGL対応が新たに」参照)。CreateJS Blogの記事「Getting Started with StageGL」には、これまでのStageStageGLに置き替えるときの要点がかいつまんで紹介されています。そこで、jsdo.itのいくつかの簡単な作例で、StageStageGLに変えて動かしてみます(「EaselJS: StageGL()コンストラクタ」参照)。

ステージの色はグレーがデフォルト

はじめは、ふたつのShapeインスタンスをドラッグ&ドロップする作例です(図001)。つぎのように、コンストラクタStage()StageGL()に書き替えます。

var stage;
var canvasElement = document.getElementById("myCanvas");
// stage = new createjs.Stage(canvasElement);
stage = new createjs.StageGL(canvasElement);

図001■EaselJS 0.8.2: EaselJSでマウスクリックとドラッグ&ドロップを扱う

170523_stagegl_001.png
>> jsdo.itへ

すると、Shapeインスタンスが消えて、ステージがグレーに変わります。StageGLの背景色はグレーがデフォルトなのです(「My background is grey」参照)。色はStage.setClearColor()メソッドによって決めます。引数にカラー名は使えないものの、RGBAカラー値が渡せます

stage.setClearColor('#FFFFFF');
// stage.setClearColor(0xFFFFFFFF);  // RGBAカラー値も可

StageGL()コンストラクタの第2引数に渡すオブジェクトで、transparentプロパティをtrueに定めれば、背景は透過できます。ただし、負荷が高いので、できれば避けたほうがよいでしょう。CodePen「Background Transparency」にデモが掲げられています。

var stage = new createjs.StageGL(canvasElement, {transparent: true});

Shapeオブジェクトはキャッシュする

WebGLはラスターグラフィックス(ビットマップ画像)とポリゴンメッシュを描くようにつくられています。ところが、ShapeとTextのインスタンスはベクター形式のデータです。そのため、ステージから消えてしまうのです。これらのオブジェクトは、キャッシュすればラスタライズされるので表示できるようになります。

function createCircle(nX, nY, nRadius) {
    var myShape = new createjs.Shape();
    var nThickness = 1;
    var half = nRadius + nThickness;

    myShape.cache(-half, -half, half * 2, half * 2);

}

キャッシュしたイメージはテクスチャの中に描かれて、再利用されます。表示オブジェクトのキャッシュについてはDisplayObject.cache()メソッドをご参照ください。

前掲の作例のStageStageGLに替えて動くようにしたのが「EaselJS NEXT: Using StageGL with shapes」です。DisplayObject.cache()メソッドには、引数でキャッシュする領域を渡します(前掲コード参照)。このとき、Shapeインスタンスに描く線の太さも含めることに気をつけましょう。

フィルタはそのまま使える

ふたつ目の作例は、読み込んだビットマップ画像にフィルタを加えます。読み込み待ちにはImageLoaderクラスを使いました。画像はBlurFilterでぼかし、ドラッグする軌跡にAlphaMaskFilterを加えることでくっきりした画像が描き出されます(図002)。

図002■ドラッグする軌跡でアルファマスクを描く

170523_stagegl_002.png
>> jsdo.itへ

この作例のコンストラクタStage()StageGL()に書き替えたのが「EaselJS NEXT: Using StageGL with filters」です。ふたつのフィルタは何の手も加えずに動きました。ビットマップ画像の扱いや読み込み待ちもコードはそのままです。

ただ、カーソル代わりに動かしていたShapeインスタンスは、前の作例と同じくキャッシュしなければなりませんでした。

function createCursor() {
    cursor = new createjs.Shape();

    cursor.cache(-radius, -radius, radius * 2, radius * 2);

}

処理を速める

Shapeオブジェクトは、キャッシュすることでStageGLに描くことができます。けれど、Stageを使った場合と比べて、処理が速くなるとはかぎりません。

たとえば、「EaselJS 1.0.0 + ES6: Bursting particles animation with StageGL」の作例です。1ピクセルのShapeインスタンス3,000個をStageGL上でマウスポインタに合わせて弾けるようにアニメーションさせています。Stageオブジェクトを使ったもとの「EaselJS 0.8.0: Bursting particles animation with the linked list」と比べると、明らかに遅くなっています。

WebGLの速さを活かすには、オブジェクトそのものをビットマップにするのがよいでしょう。「EaselJS 1.0.0 + ES6: Bursting particles animation with StageGL」は、パーティクルのPGN画像をBitmapインスタンスに読み込みました。この作例では粒子数を10倍の30,000個にし、表示領域も拡げています。それでも動きの滑らかさは、もとの例と変わりません。

WebGLの処理を最適化するには、読み込むビットマップ画像は一辺が2の累乗の正方形にしておきます(「I don’t like the image quality」参照)。これはWebGLの制約で、WebGL 2.0では取り除かれるようです。

実際に用いるイメージは、一辺が2の累乗とか、正方形でなくて構いません。使う領域は、Bitmap.sourceRectプロパティRectangleオブジェクトで定めて切り抜きます。スプライトシートを使うのは有効でしょう。

var imageWidth = 180;
var imageHeight = 180;

function draw(eventObject) {
    var image = eventObject.result;

    // var imageWidth = imageSize.x = image.width;
    // var imageHeight = imageSize.y = image.height;
    imageSize.x = image.width = imageWidth;
    imageSize.y = image.height = imageHeight;

}
function createBitmap(image, nX, nY) {
    var myBitmap = new createjs.Bitmap(image);

    myBitmap.sourceRect = new createjs.Rectangle(0, 0, 180, 180);

}

ビットマップイメージの拡大や回転をするとき、StageGL()コンストラクタの第2引数で、antialiasプロパティにtrueを与えれば滑らかに表示されます(読み込む画像は一辺が2の累乗の正方形にしなければなりません)。ただし、負荷は高まるでしょう。前出「Getting Started with StageGL」の比較画像をお確かめください。

Canvasの領域を変えたとき

Canvasの幅や高さを変えたとき、WebGLに新たなサイズを伝えなければ正しく描画されません。そのためには、StageGL.updateViewport()メソッドを呼び出します。CodePen「Resizing」のデモで結果が確かめられます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした