-
lynda.com
ビデオライブラリー -
Webクリエイターのための
CreateJSスタイルブック -
gihyo.jp連載
「Away3D TypeScriptで
はじめる3次元表現」 -
gihyo.jp連載
「CSS3アニメーションでつくる
インターフェイス表現」
CreateJS Workshop vol.07
EaselJS 0.8.2の改訂項目とgskinner labの作例「Arc Rainbow」
まず、2015年11月26日にビルドが改められたEaselJS 0.8.2について、改訂されたおもな項目を簡単に紹介する。つぎに、gskinnerチームの習作が公開されているLabから「Arc Rainbow」を採り上げ、その中で用いられているGraphicコマンドなどの技術を解説しよう。
01 EaselJS 0.8.2で改訂されたおもな項目
CreateJS 2015年11月26日付ビルドのライブラリごとの細かな改訂項目は、それぞれに付属するVERSIONS.txtの一覧にもとづいて以下のノートにまとめた。ここではEaselJS 0.8.2のおもな改訂についてご紹介する。
- 「EaselJS 0.8.2: 改訂された項目」
- 「PreloadJS 0.6.2: 改訂された項目」
- 「SoundJS 0.6.2: 改訂された項目」
- 「TweenJS 0.6.2: 改訂された項目」
EaselJSライブラリのコンパクト版にMovieClipクラスが含まれた
MovieClip
クラスは、EaselJSライブラリのコンパクト(min)版に含まれた(図001)。したがって、MovieClip
クラスのコンパクト版は提供されない。
図001■MovieClipクラスはEaselJSライブラリに含まれた
SpriteSheetクラスのイメージの扱いにエラーの処理を追加
SpriteSheet
クラスにSpriteSheet.error
イベントが加わり、イメージの扱いにエラーが起きたときの処理を定められるようになった。
- SpriteSheet.errorイベント
イメージが正しく扱えなかったとき、そのソースごとに生じるイベント。このイベントが起こった場合でも、すべてのイメージの扱いを終えればSpriteSheet.complete
イベントが呼び出される。SpriteSheet.error
のイベントオブジェクトは、src
プロパティに読み込めなかったイメージのURLをもつ。
SpriteSheetBuilder()コンストラクタの引数でSpriteSheet.framerateプロパティの値が定められる
SpriteSheetBuilder
クラスでSpriteSheet
オブジェクトをつくるとき、SpriteSheetBuilder()
コンストラクタの引数でSpriteSheet.framerate
プロパティの値が定められるようになった(デフォルト値は0でTicker
クラスの定めにしたがう)。
SpriteSheetBuilder(フレームレート)
SpriteSheetBuilder.animations()メソッドがspeedプロパティに対応
また、SpriteSheetBuilder.addAnimation()
メソッドの第4引数は、速さのプロパティとしてfrequency
でなくspeed
を与えるように改められた。EaselJS 0.7.0でSpriteSheet()
コンストラクタに渡すオブジェクトのanimations
プロパティに定める再生の速さのプロパティが、frequency
からspeed
に変わったことに合わせた(「EaselJS 0.7.0の改訂」01「重要な変更(旧コンテンツとの互換性を損なう)」参照)。
- frequency
DisplayObject.tick
イベント何回ごとに進めるかという頻度 - speed
speed
= 1 /frequency
クラスの内部における配列の判別処理をArray.isArray()メソッドに改訂
クラスSpriteSheet
とPreloadJSのLoadQueue
の内部処理で、配列かどうかを確かめるのにinstanceof
演算子でなくArray.isArray()
メソッドが用いられるようになった(「オブジェクトが配列かどうかを確かめる」参照)。
- Array.isArray()メソッド
- オブジェクトそのものが配列かどうかを確かめる
- ECMAScript 5.1以降
- instanceof演算子
- オブジェクトのプロトタイプチェーンにコンストラクタ関数があるかどうかを確かめる
- 異なるグローバル空間(
window
オブジェクト)のArray
クラスは別とみなされる - ECMAScript 3以降
バグの修正
- DisplayProps.setValues()メソッド
第4引数が、DisplayProps.compositeOperation
プロパティの値に正しく定められるようになった(「EaselJS 0.8.0: DisplayPropsクラス」注[*2]参照)。DisplayProps()
コンストラクタの問題も併せて解消された。 - Graphics.StrokeStyle()メソッド
第5引数が、Graphics.Stroke.ignoreScale
プロパティの値に正しく定められるようになった。
02 gskinner labの作例「Arc Rainbow」
Grant Skinner氏による作例「Arc Rainbow」にもとづき、コードの構造をわかりやすく整えたのがつぎのサンプル001だ。EaselJSのGraphics.command
プロパティを使っている。
サンプル001■CreateJS 15/11/26: Arc Rainbow
Graphicsコマンドでトゥイーンアニメーションを描く
前掲サンプル001の中で円弧のアニメーションのみ抜き出したのが、つぎのサンプル002になる。以下に抜き出したコードのようにGraphics.arc()
メソッドは初めに1度しか呼び出されていない。Ticker.addEventListener()
メソッドにTicker.tick
イベントのリスナーとしてStage
オブジェクトを渡しているので、Ticker.tick
イベントではStage.update()
メソッドが呼び出されるだけだ(「EaselJS 0.8.1: イベントリスナーを扱うEventDispatcher」「説明」参照)。それでも、円弧が描き直されている。
サンプル002■CreateJS 15/11/26: Arc tween animation with Graphics command
function initialize(eventObject) { draw(); stage.update(); createjs.Ticker.addEventListener("tick", stage); } function draw() { graphics.setStrokeStyle(10 + Math.random() * 10) .beginStroke(color); var arcCommand = graphics.arc(0, 0, 50, randomAngle, randomAngle).command; }
Graphicsコマンドを使わず、円弧は関数(update())で描き変えるとすれば、たとえばつぎのようにTween.change
イベントのリスナーに定めることになる。トゥイーンする円弧を描くためにGraphics.arc()
メソッドに渡す引数値はオブジェクト(settings)に定め、それをトゥイーンの対象としてTween.get()
メソッドに与えた。これで円弧がトゥイーンアニメーションで描ける。
var settings; function draw() { graphics.setStrokeStyle(thickness) .beginStroke(color); .arc(0, 0, 50, randomAngle, randomAngle); settings = {endAngle: randomAngle, startAngle: randomAngle, color:color, thickness: thickness} var tween = createjs.Tween.get(settings, {loop: true}) .to({endAngle: angle}, Math.random()* angle * 100 + 3000, createjs.Ease.easeOut) .to({startAngle: angle}, Math.random() * 1000 + 3000, createjs.Ease.easeIn); tween.addEventListener("change", update); } function update(eventObject) { graphics.clear() .setStrokeStyle(settings.thickness) .beginStroke(settings.color) .arc(0, 0, 50, settings.startAngle, settings.endAngle); stage.update(); }
Graphics.command
プロパティから得たGraphicsコマンド(arcCommand)をトゥイーンするなら、上のコードがつぎのように書き替えられる。Tween.get()
メソッドには、Graphicsコマンドをトゥイーンの対象として渡した。すると、円弧を書き直すための関数(update())は要らなくなる。
// var settings; function initialize(eventObject) { draw(); stage.update(); createjs.Ticker.addEventListener("tick", stage); } function draw() { graphics.setStrokeStyle(thickness) .beginStroke(color); // .arc(0, 0, 50, randomAngle, randomAngle); var arcCommand = graphics.arc(0, 0, 50, randomAngle, randomAngle).command; // settings = {endAngle: randomAngle, startAngle: randomAngle, color:color, thickness: thickness} // var tween = createjs.Tween.get(settings, {loop: true}) var tween = createjs.Tween.get(arcCommand, {loop: true}) .to({endAngle: angle}, Math.random()* angle * 100 + 3000, createjs.Ease.easeOut) .to({startAngle: angle}, Math.random() * 1000 + 3000, createjs.Ease.easeIn); // tween.addEventListener("change", update); } /* function update(eventObject) { var graphics = shape.graphics; graphics.clear() .setStrokeStyle(settings.thickness) .beginStroke(settings.color) .arc(0, 0, 50, settings.startAngle, settings.endAngle); stage.update(); } */
Graphics APIは内部的にGraphicsコマンドを使って描画している(「EaselJS 0.8.0: Graphicsクラス」参照)。その手順はCanvas APIに近い。Graphics.arc()
メソッドを呼び出すとGraphics.Arc
クラスのコマンドオブジェクトがつくられ、Graphics.command
プロパティから返される。
Graphics.Arc
コマンドオブジェクトは円弧の開始角と終了角を、それぞれプロパティGraphics.Arc.startAngle
とGraphics.Arc.endAngle
にもつ。そのため、それらのプロパティはTween
クラスでトゥイーンさせることができ、画面が描き替わるとき(Stage.update()
メソッド呼び出し時)に表示は改められる(「Graphicsコマンドでトゥイーンアニメーションを描く」参照)。
DisplayObjectインスタンスにドロップシャドウを加える
DisplayObject
インスタンスのDisplayObject.shadow
プロパティにShadow
オブジェクトを定めると、ドロップシャドウが加わる。ドロップシャドウを消すには、プロパティにnull
を与えればよい。Shadow()
コンストラクタは、つぎのように4つの引数をとる(デフォルト値は色が黒("black")、あとの3つの引数は0)。
new Shadow (色, 水平のずれ, 垂直のずれ, ぼかし幅)
つぎのコードは、Shapeインスタンス(shape)にドロップシャドウ(shadow)を加える。DisplayObjectインスタンスがひとつでも、影は描画ごとにかかる(図002)。
var shape = new createjs.Shape(); var shadow = new createjs.Shadow("#000", 2, 2, 20); shape.shadow = shadow;
図002■CreateJSとFlash Playerでひとつのオブジェクトにふたつの描画を加えたときの影の違い
オンとオフを切り替える処理
前掲の作例「Arc Rainbow」では、ドロップシャドウのオン・オフを切り替える関数(toggleShadow())はつぎのように定められている(変数名は本稿のサンプルに揃えて変えた。図3参照)。ただ、一見してわかりにくい。これは、関数にブール(論理)値の引数を渡したとき、オン・オフのどちらにするか決められるようにしたためだ。また、条件の評価も、関数を引数なしに呼び出したとき、影をつけるときは3つ、消すときには6つすべて評価しなければならず無駄である。
function toggleShadow(show) { if (show == true || (show == null && shape.shadow == null)) { shape.shadow = shadow; } else if (show === false || (show == null && shape.shadow != null)) { shape.shadow = null; } }
図003■gskinnerのLabの「Arc Rainbow」が定めている関数
そこでコードを見やすくし、無駄を減らすため、前掲サンプル001ではつぎのふたつの手が加えてある。
- 関数の引数がブール値でなければオン・オフの切り替えとする
- コード行数は条件(三項)演算子
?:
を使って減らす
項目1は、ブール値とnull
(undefined
)以外を無視するかどうかだ。そうしたい場合には、else if
条件を加えればよいだろう。項目2は、いずれの場合もプロパティへの代入がともなうので採り入れた。if
文を使っても、処理効率は問題ない(「設定のオン・オフを切り替える - トグルボタンの論理組み立て」参照)。コードはつぎのとおりだ。どの場合であっても、ふたつの条件の評価で処理が決まる。
function toggleShadow(show) { if (typeof show == "boolean") { shape.shadow = show ? shadow : null; } else { shape.shadow = (shape.shadow == null) ? shadow : null; } }
Appendix Grant Skinner氏からの最新情報
もうすぐ公開されるWebGL向けのクラスSpriteStage
では、SpriteContainer
オブジェクトを使わなくてもよくなり、速さや柔軟性が増す。正規リリース1.0も具体的な計画が進んでいる。
作成者: 野中文雄
作成日: 2016年1月23日
Copyright © 2001-2016 Fumio Nonaka. All rights reserved.