-
LinkedInラーニング
ビデオライブラリー -
Webクリエイターのための
CreateJSスタイルブック -
gihyo.jp連載
「HTML5のCanvasでつくるダイナミックな表現
―CreateJSを使う」
ビデオライブラリー: 「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
>>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アカウント
02-01 StageをStageGLに替えてShapeオブジェクトはキャッシュする
まず、Stage
はStageGL
に替えて、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()
コンストラクタに渡す引数オブジェクトで、preserveBuffer
とantialias
のプロパティを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の描画が消えずに残る
つぎに、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■円が左右にトゥイーンアニメーションする
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ファイル
静的メソッド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.