サイトトップ

Director Flash 書籍 業務内容 プロフィール

ビデオライブラリー: 「CreateJS 基本講座
■Twitter: @FumioNonaka / Facebook Page: CreateJS


CreateJS Workshop vol.09

CreateJS 1.0.0で何が変わったか

CreateJSがついに正規バージョン1.0.0としてリリースされた。新たに備わった機能として大きいのがWebGLへの対応だろう。もっとも、それ以外の新機能はどれも粒が小さい。おそらく正規版のリリースとして、最適化や拡張性、安定性など、内部的な改善に力が注がれたものと考えられる。そういうわけで、少しマニアックな機能も含めて、CreateJS 1.0.0で何が変わったのかを紹介したい。


* 本稿の一席は29:25〜。なお、49:08で映像が一部途切れている。

01 StageGLクラスでStageを置き替えてWebGLが使えるようにするには

CreateJS 1.0.0のStageGLでStageを置き替える」ときの基本からご紹介する。ドラッグ&ドロップするShapeオブジェクトの作例(サンプル001)を、StageからStageGLクラスに置き替えてみよう。

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

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

コンストラクタStage()の呼び出しはStageGL()に替える。ステージの色はグレーがデフォルトになる。変えたいときは、StageGL.setClearColor()メソッドにカラー値を渡す(整数値でもよい。カラー名は使えない)。なお、JavaScriptの構文はECMAScript 6にもとづくこととする。


let stage;
const canvasElement = document.getElementById('myCanvas');
// stage = new createjs.Stage(canvasElement);
stage = new createjs.StageGL(canvasElement);
stage.setClearColor('#FFFFFF');

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

つぎに、WebGLはラスターグラフィックス(ビットマップ画像)とポリゴンメッシュを描くようにつくられている。Shapeインスタンスはベクター形式のデータなので、ラスタライズするためにはキャッシュしなければならない。これで、Shapeオブジェクトを使った簡単なコンテンツなら、StageGLで動かせるようになる(サンプル002)。


function createCircle(nX, nY, nRadius) {
	const myShape = new createjs.Shape();

	myShape.cache(-nRadius, -nRadius, nRadius * 2, nRadius * 2);
	return myShape;
}

サンプル002■EaselJS NEXT: Using StageGL with shapes

[*1] Shapeオブジェクトに線を加えて描いた場合には、キャッシュ領域に線幅も含めなければならない。


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

	// myShape.cache(-nRadius, -nRadius, nRadius * 2, nRadius * 2);
	myShape.cache(-half, -half, half * 2, half * 2);
	return myShape;
}

01-03 使える機能と使えない機能

フィルタの多くは使える。つぎのサンプル003の画像はBlurFilterでぼかし、ドラッグする軌跡にAlphaMaskFilterを加えることでくっきりした画像が描き出される。実際に試したところでは、ColorMatrixFilterクラスも動いた。

サンプル003■EaselJS NEXT: Using StageGL with filters

サンプル003
>>jsdo.itへ (埋め込みではcross-originの制限がかかるため)

DisplayObject.maskプロパティShapeインスタンスを定めても、StageGLではマスクがかからない(サンプル004の初期設定はStage)。

サンプル004■CreateJS 1.0.0: Shape mask does not work on StageGL

DisplayObject.compositeOperationプロパティは、表示オブジェクト(DisplayObject)の合成とクリッピングを操作する。設定値の中でlighterは、重なりのカラー値を加算して明るくする。多くの表現で使われる(サンプル005)。しかし、StageGLではこの効果が働かない(サンプル006の初期設定はStage)。

サンプル005■CreateJS 1.0.0 + ES6: Particles

サンプル006■CreateJS 1.0.0: StageGL cannot use lighter for compositeOperation


02 パーティクルのアニメーションをStageGLで動かす

最近、CodePenにCreateJSがアカウントを設けた。そこに掲げられた「CreateJS: Bursting particles animation with the linked list」は、jsdo.itの「EaselJS 0.8.0: Bursting particles animation with the linked list」をStageGLに合わせて書き改めている。その場合の要点を確かめたい(詳しくは「CreateJS 1.0.0 + ES6: パーティクルのアニメーションをStageGLで動かす」参照)。

図001■CodePenのCreateJSアカウント

図001

02-01 StageをStageGLに替えてShapeオブジェクトはキャッシュする

まず、StageStageGLに替えて、StageGL.setClearColor()メソッドで背景色を定める。


let stage;

const color = '#19101C';
function initialize() {

	// stage = new createjs.Stage(canvasElement);
	stage = new createjs.StageGL(canvasElement);
	stage.setClearColor(color);

}

つぎに、パーティクルのShapeオブジェクトはキャッシュする。これでパーティクルはStageGLのもとで動く(サンプル007)。けれど、キャッシュしたShapeオブジェクトの動きは、もとのStageにおけるアニメーションより遅い。


class Particle extends createjs.Shape {

	drawParticle() {
		const radius = this.radius ;
		const size = radius * 2;
		this.graphics.beginFill('white')
		.drawRect(-radius, -radius, size, size);
		this.cache(-radius, -radius, size, size);
	}
}

サンプル007■EaselJS 1.0.0 + ES6: Bursting particles animation with StageGL

02-02 ShapeからBitmapオブジェクトをつくる

キャッシュで済まさず、パーティクルをビットマップでつくらないと、WebGLの速さが活かせない。DisplayObject.cacheCanvasプロパティで、キャッシュしたイメージをもったHTMLCanvasElementが得られるので、Bitmap()コンストラクタに渡せばビットマップのオブジェクトがつくれる。<canvas>要素はひとつあれば、Bitmapインスタンスはいくつでもできる。


class Particle extends createjs.Shape {

	/* drawParticle() {
		...[中略]...
	} */

}

const numParticles = 30000;  // 3000;
function initialize() {

	stage = new createjs.StageGL(canvasElement);

	// createParticles(numParticles);
	createParticles(numParticles, 0.5);

}

function drawParticle(radius) {
	const shape = new createjs.Shape();
	const size = radius * 2;
	shape.graphics.beginFill('white')
	.drawRect(-radius, -radius, size, size);
	shape.cache(-radius, -radius, size, size);
	return shape.cacheCanvas;
}
// function createParticles(amount) {
function createParticles(amount, radius) {
	const bit = drawParticle(radius);
	for (let i = 0; i < amount; i++) {

		const particleImage = new createjs.Bitmap(bit);
		// const particle = new Particle(_x, _y, stageWidth, stageHeight);
		const particle = new Particle(particleImage, _x, _y, stageWidth, stageHeight);

	}
}

パーティクルのクラス(Particle)は、ShapeでなくContainerクラスを継承させる。そして、Bitmapインスタンス(image)は、オブジェクトの子に加えた。これで、パーティクルの数を10倍に増やしても、滑らかにアニメーションする(サンプル008)。


// class Particle extends createjs.Shape {
class Particle extends createjs.Container {
	// constructor(x, y, right, bottom) {
	constructor(image, x, y, right, bottom) {
		super();

		// this.radius = 0.5;
		// this.drawParticle();
		this.addChild(image);
	}

}

サンプル008■EaselJS 1.0.0 + ES6: Bursting Bitmap particles animation with StageGL

02-03 パーティクルの残像を描く

CodePenの作例の方が、パーティクルは密になっているように見える。パーティクルの残像が加えられていたためだ。まず、StageGL()コンストラクタに渡す引数オブジェクトで、preserveBufferantialiasのプロパティをtrueに定める。そのうえでStage.autoClearプロパティfalseにすると、Canvasへの描画は消えずにそのまま残る(図002)。


function initialize() {

	// stage = new createjs.StageGL(canvasElement);
	stage = new createjs.StageGL(canvasElement, {preserveBuffer: true, antialias: true});
	stage.autoClear = false;

}

図002■Canvasの描画が消えずに残る

図002

つぎに、Canvasと同じサイズのShapeインスタンスを重ね、背景と同じ色に薄いアルファ(DisplayObject.alphaプロパティ)を与える。このオブジェクトは再描画(Ticker.tickイベント)のたびに塗り重なるので、古いパーティクルから徐々に消えてゆく。これで、残像の効果が加わった。


let fader;
const color = '#19101C';
function initialize() {

	fader = createFader(stageWidth, stageHeight);
	stage.addChild(fader);

}

function createFader(width, height) {
	fader = new createjs.Shape();
	resetFader(width, height);
	return fader;
}
function resetFader(width, height) {
	fader.graphics.beginFill(color)
	.drawRect(0, 0, width, height);
	fader.cache(0, 0, width, height);
	fader.alpha = 0.15;
}

パーティクルのアニメーションそのものはこれででき上がりだ。CodePenの作例に合わせて細かなおまけを加え、ECMAScript 6の構文に改めて整理したコードをサンプル009として掲げる(詳しくは「CreateJS 1.0.0 + ES6: パーティクルのアニメーションをStageGLで動かす」参照)。

サンプル009■EaselJS 1.0.2 + ES6: Bursting particles animation with StageGL


03 TweenJSのプラグインを使う

つぎのJavaScriptコードで、円形のShapeオブジェクトがTweenクラスにより左右にトゥイーンアニメーションする(図003)。Tween()コンストラクタに渡すオプションオブジェクトのloopプロパティの値が回数を示す数値に変わったことに注意。ずっと繰り返すときには-1を定める。


let stage;
function init() {
	const radius = 25;
	const duration = 2000;
	const canvasElement = document.getElementById('myCanvas');
	stage = new createjs.Stage(canvasElement);
	const circle = new createjs.Shape();
	const graphics = circle.graphics;
	graphics.beginFill('hsl(180, 100%, 50%)');
	graphics.drawCircle(0, 0, radius);
	circle.x = radius;
	circle.y = canvasElement.height / 2;
	stage.addChild(circle);
	createjs.Tween.get(circle, {loop: -1, bounce: true})
	.to({x: canvasElement.width - radius}, duration, createjs.Ease.quadInOut);
	createjs.Ticker.timingMode = createjs.Ticker.RAF;
	createjs.Ticker.addEventListener('tick', stage);
}

図003■円が左右にトゥイーンアニメーションする

図003

03-01 SamplePluginクラスを使う

TweenJS 1.0.0で、プラグインモデルが大幅に改められた(「CreateJS: TweenJS 1.0.0アップデート」参照)。プラグインはダウンロードしたTweenJSライブラリの「pulgins」フォルダに納められている(図004)。その中のSamplePluginを試してみる。

<head>要素

<script src="lib/SamplePlugin.js"></script>

図004■TweenJSライブラリに含まれるプラグインのJavaScritpファイル

図004

静的メソッドSamplePlugin.install()でプラグインをインストールするだけで、x座標の動きに応じてy座標がsin関数で上下に揺れる。SamplePluginクラスの応用性は高くない。プラグインをつくる人向けのデモ用のクラスなので、SamplePlugin.jsのソースにはコメントが詳しく加えられている(「CreateJS: TweenJS 1.0.0のプラグインを使う」参照)。


createjs.SamplePlugin.install();
createjs.Tween.get(circle, {loop: -1, bounce:true})
.to({x: canvasElement.width - radius}, duration, createjs.Ease.quadInOut);

03-02 ColorPluginクラスを使う

ColorPluginクラスは、CSSのカラーの定めにしたがった文字列の値をトゥイーンする。ただし、カラー名は使えない。

<head>要素

<script src="lib/ColorPlugin.js"></script>

プラグインを静的メソッドColorPlugin.install()でインストールする。引数は色をトゥイーンするモードで、デフォルト値は'rgb'で、今回は'hsl'とした。


createjs.ColorPlugin.install('hsl');

トゥイーンしたいのは、円形のShapeインスタンスの塗り色だ。そのためには、円の描画そのものを繰り返さなければならないようにみえる。


const graphics = circle.graphics;
graphics.beginFill('hsl(180, 100%, 50%)');
graphics.drawCircle(0, 0, radius);

Graphics.commandプロパティを使えばGraphics.Fillコマンドオブジェクトの参照が得られるので、Graphics.Fill.styleプロパティのカラー値をhsl()のかたちでトゥイーンすればよい。これで、円が波のように揺れ動きつつ色を変えるアニメーションになる(サンプル010)。


var graphics = circle.graphics;
var fillCommand = graphics.beginFill('hsl(180, 100%, 50%)').command;

createjs.ColorPlugin.install('hsl');

createjs.Tween.get(fillCommand, {loop: -1, bounce:true})
.to({style: 'hsl(360, 100%, 50%)'}, duration, createjs.Ease.quadInOut);

サンプル010■TweenJS 1.0.0: Using plugins


04 FontLoaderクラスでwebフォントを読み込む

新たに備わったFontLoaderクラスは、フォントファイルやCSS定義およびCSSパスを読み込む。フォントそのものをプリロードするのではなく、CSS定義をつくって、フォントファイルやCSSパスを扱う。FontLoader()コンストラクタには、読み込む項目の内容が定められたオブジェクトを渡す。つぎのコードは、GoogleフォントRobotoを読み込んで、要素(element)に適用する(サンプル011)。


var loader = new createjs.FontLoader({
	src: 'https://fonts.googleapis.com/css?family=Roboto:400,700,400italic,700italic',
	type: 'fontcss'
});
loader.addEventListener('complete', function() {
	element.style.fontFamily = 'Roboto';
});
loader.load();

サンプル011■PreloadJS 1.0.0: Loading Google font


作成者: 野中文雄
更新日: 2017年12月8日 YouTube映像を追加。
作成日: 2017年12月7日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.