|
||||||||||||||||||||||
CreateJS Workshop 外部ファイルの読込みとサウンドの再生
|
|
EaselJSを使うには、まずCanvasにステージ(Stageオブジェクト)をつくらなければならない。new演算子でStageクラスのコンストラクタを呼出し、引数にはcanvas要素の参照を渡す。なお、CreateJSのクラスを参照するときは、頭に「名前空間」として「createjs」を添える。
new createjs.Stage(canvas要素)
canvas要素の参照は、document.getElementById()メソッドにidを渡すと得られる(第5行目)。初期設定の関数(initialize())で、Stageオブジェクトをつくった(第6行目)。
- var stage;
- function initialize() {
- var canvasElement = document.getElementById("myCanvas");
- stage = new createjs.Stage(canvasElement);
- }
画像イメージはBitmapインスタンスに入れる。new演算子でBitmapクラスのコンストラクタを呼出し、引数には外部画像ファイルのURLを渡す。
new createjs.Bitmap(画像ファイルのURL)
インスタンスをCanvasに表示するためには、Stageオブジェクトの子に加えなければならない。Stageオブジェクトに対してContainer.addChild()メソッドを呼出し、加えたい子オブジェクトを引数に渡す。
親オブジェクト.addChild(子オブジェクト)
Bitmapインスタンスをつくる関数(createBitmap())は、別に定めた(第12〜17行目)。関数の引数に配置するxy座標と画像ファイルのURLを渡すと、つくったインスタンスが返される(第8行目)。そのインスタンスをStageオブジェクトの子に加えている(第9行目)。なお、Canvasの描画を更新するためには、必ずStage.update()メソッドを呼出さなければならない(第10行目)。
- function initialize() {
- var url = "images/Pen.png";
- var myBitmap = createBitmap(canvasElement.width / 2, canvasElement.height / 2, url);
- stage.addChild(myBitmap);
- stage.update();
- }
- function createBitmap(nX, nY, url) {
- var myBitmap = new createjs.Bitmap(url);
- myBitmap.x = nX;
- myBitmap.y = nY;
- return myBitmap;
- }
script要素全体を以下のコード001にまとめた。まだ、でき上がりではない。HTMLドキュメントを開くと、何もCanvasに描かれず、とくにエラーもでない。再読込みをすれば、画像は表れる(図001)。ただし、Bitmapインスタンスの基準点は、デフォルトでは左上角に置かれる。
図001■ドキュメントを再読込みしないと画像が表れない
|
画像イメージが初めに表れないのは、読込みをまたずにStage.update()メソッドを呼出しているからだ。そこで、PreloadJSライブラリを使って読込み待ちすることになる。
まず、PreloadJSライブラリをscript要素に読込む。最新バージョンは0.3.0だ。ステートメントの行番号は、後でscript要素全体を掲げるコード002にもとづく。
- <script src="lib/preloadjs-0.3.0.min.js"></script>
PreloadJSライブラリの名前は変わらないものの、おもに用いられるクラス名がPreloadJSからLoadQueueに変わった。LoadQueueクラスのコンストラクタには、引数にXMLHttpRequest(XHR)を使うかどうかのブール(論理)値を渡す(第9行目)。
new createjs.LoadQueue(XMLHttpRequestの使用)
読込み終えたときに呼出す関数は、EventDispatcher.addEventListener()メソッドでLoadQueue.fileloadイベントにリスナーとして定める(第11行目)。
LoadQueue.loadFile()メソッドに外部ファイルのパスを文字列で渡せば、読込みが始まる(第12行目)。
LoadQueue.loadFile(読込むファイルのURL)
LoadQueue.fileloadイベントのリスナー関数(draw())は、Stage.update()メソッドの呼出しによりステージを書替える(第21〜23行目)。そのため、初期設定の関数(initialize())はメソッドを呼出さなくてよい。
- function initialize() {
- var url = "images/Pen.png";
- var loader = new createjs.LoadQueue(false);
- loader.addEventListener("fileload", draw);
- loader.loadFile(url);
// stage.update();
- }
- function draw(eventObject) {
- stage.update();
- }
ここまで書き加えたスクリプトは、つぎのコード002のとおりだ。これで、HTMLドキュメントを初めて開いても、画像ファイルの読込みを待ってステージが描かれる。
コード002■PreloadJSで外部画像ファイルの読込みを待つ
|
ステージに置かれたBitmapインスタンスの基準点は、まだデフォルトの左上角にあるままだ。これを画像イメージの真ん中に移したい。基準点はDisplayObject.regXとDisplayObject.regYプロパティで変えられる。けれど、Bitmapオブジェクトにはwidthやheightといったプロパティはない。読込んだ画像イメージの大きさは、LoadQueue.fileloadイベントのリスナー関数が受取るイベントオブジェクトからresultプロパティで調べる。
Bitmapインスタンスの基準点を変えるには、オブジェクトの参照を何らかのかたちで得なければならない。もちろん、グローバルな変数に入れれば簡単だ。けれど、ここではLoadQueue.loadFile()メソッドで渡してみる。
LoadQueueオブジェクト.loadFile({src:読込むファイルのURL, data:任意のデータ})
LoadQueue.loadFile()メソッドの引数にはURLの文字列でなく、Objectインスタンスが渡せる。URLはオブジェクトのsrcプロパティに定める。さらに、dataプロパティとして任意のデータが加えられる。ここにBitmapインスタンスを入れよう(第9行目)。抜書きした行番号は、後にスクリプト全体をまとめたコード003にもとづく。
LoadQueue.fileloadイベントのリスナー関数(draw())は、引数に受取ったイベントオブジェクトのitemプロパティからdataプロパティに与えたデータが取出せる(第19行目)。
- function initialize() {
- var url = "images/Pen.png";
- var loader = new createjs.LoadQueue(false);
- var myBitmap = createBitmap(canvasElement.width / 2, canvasElement.height / 2, url);
- loader.addEventListener("fileload", draw);
// loader.loadFile(url);- loader.loadFile({src:url, data:myBitmap});
- }
- function draw(eventObject) {
- var myBitmap = eventObject.item.data;
- var myImage = eventObject.result;
- myBitmap.regX = myImage.width / 2;
- myBitmap.regY = myImage.height / 2;
- stage.update();
- }
これで、LoadQueue.fileloadイベントのリスナー関数(draw())は、読込んだ画像の大きさにもとづいて、Bitmapインスタンスの基準点を画像イメージの真ん中に定める(図002)。スクリプト全体は、以下のコード003のとおりだ。
図002■読込んだ画像メージの大きさにもとづいてBitmapインスタンスの基準点が中心に定められた
|
外部MP3サウンドファイルをPreloadJSで読込んで、SoundJSを用いて再生する。ふたつのライブラリはCanvasが要らないので、EaselJSは使わなくてよい。
script要素には、PreloadJSとSoundJSのライブラリを読込む。SoundJS 0.4.0でおもに用いるクラス名が、SoundJSからただのSoundに変わった。サウンドの操作の仕方も前のバージョンとは異なる。
- <script src="lib/preloadjs-0.3.0.min.js"></script>
- <script src="lib/soundjs-0.4.0.min.js"></script>
LoadQueueクラスを用いた外部サウンドファイルの読込み方は、基本的に画像ファイルの場合と同じ。ただし、LoadQueue.installPlugin()メソッドの引数にSoundクラスの参照を渡して、プラグインを登録しなければならない(第8行目)。抜書きするステートメントの行番号は、後にscript要素に書いたスクリプト全体を掲げるコード004にもとづく。
LoadQueueオブジェクト.installPlugin(createjs.Sound)
LoadQueue.loadFile()メソッドに渡すObjectインスタンスには、idプロパティを定めておくと、後でサウンドが扱いやすい(第10行目)。
- function initialize() {
- var url = "sounds/test.mp3";
- var loader = new createjs.LoadQueue(false);
- loader.installPlugin(createjs.Sound);
- loader.addEventListener("fileload", soundLoaded);
- loader.loadFile({src:url, id:"music"});
- }
LoadQueue.fileloadイベントのリスナー関数(soundLoaded())は、静的メソッドSound.play()でサウンドを再生する。メソッドの引数には、イベントオブジェクト(eventObject)のitemプロパティから前に定めた(第10行目)idプロパティの値を取出して渡す(第13〜14行目)。メソッドの返すSoundInstanceオブジェクトは、後でサウンドの操作に用いるので、グローバルな変数(instance)にとっておく(第4行目)。
createjs.Sound.play(サウンドのID)
- var instance;
- function soundLoaded(eventObject) {
- var sound = eventObject.item.id;
- instance = createjs.Sound.play(sound);
- }
つぎのコード004は、PreloadJSにより外部MP3サウンドを読込んで、SoundJSで再生する。body要素には何も加えていないので、HTMLドキュメントは空白のままだ。
コード004■PreloadJSにより外部サウンドファイルを読込んでSoundJSで再生する
|
再生しているサウンドの一時停止や再開には、SoundInstanceクラスのメソッドSoundInstance.pause()およびSoundInstance.resume()を用いる。
SoundInstanceオブジェクト.pause()
SoundInstanceオブジェクト.resume()
一時停止と再生(再開)はボタンひとつで切替えることにして、body要素にinput要素のボタンを置く(図003)。そして、JavaScriptで操作するためのid属性("control")を定めておく。
図003■body要素にはinput要素のボタンを置く
<body onLoad="initialize()">
<input type="button" value="準備中" id="control">
</body>
まず、ボタンのinput要素の参照は、グローバルな変数にとっておく(第2および第9行目)。そして、LoadQueue.fileloadイベントのリスナー関数(soundLoaded())は、ボタンのonclickイベントにサウンドの一時停止の関数(pauseSound())をハンドラとして定める(第15行目)。スクリプト全体は、後にコード005として掲げた。
ボタンがクリックされると、ハンドラ(pauseSound())がSoundInstance.pause()メソッドでサウンドを一時停止するとともに、onclickハンドラをサウンド再開の関数(resumeSound())に差替える(第19〜20行目)。再びボタンを押すと、SoundInstance.resume()メソッドにより、サウンドが再開される(第24行目)。そして、onclickハンドラの関数は一時停止(pauseSound())に戻される(第25行目)。
- var control;
- function initialize() {
- control = document.getElementById("control");
- }
- function soundLoaded(eventObject) {
- control.onclick = pauseSound;
- }
- function pauseSound(eventObject) {
- instance.pause();
- control.onclick = resumeSound;
- }
- function resumeSound(eventObject) {
- instance.resume();
- control.onclick = pauseSound;
- }
つぎのコード005は、再生されたサウンドが、ボタンを押すと一時停止し、ふたたびクリックすれば再開する。ただし、再生し終わったサウンドは、ボタンを押しても再生されない。なお、サウンドの再生状況がわかるように、ボタンのvalueプロパティの文字列を切替えている(図004)。
図004■サウンドの再生状況によりボタンの表記が変わる←→ |
|
再生が終わったサウンドを改めて頭から再生し直すにはSoundInstance.play()メソッドを用いる。また、サウンドが再生し終わったことは、SoundInstance.completeイベントで捉えられる。
SoundInstanceオブジェクト.play()
そこでまず、EventDispatcher.addEventListener()メソッドでSoundInstance.completeイベントにリスナー関数(resetSound())を加える(第15行目)。この関数は、ボタンのonclickイベントにサウンドが改めて再生されるハンドラの関数(restartSound())を定める(第30行目)。そして、ボタンが押されると、ハンドラが呼出されて、サウンドは頭から再生される(第34行目)。スクリプト全体は、後にコード006として掲げた。
- function soundLoaded(eventObject) {
- var sound = eventObject.item.id;
- instance = new createjs.Sound.play(sound);
- instance.addEventListener("complete", resetSound);
- }
- function resetSound(eventObject) {
- control.onclick = restartSound;
- }
- function restartSound() {
- instance.play();
- control.onclick = pauseSound;
- }
これで、サウンドの再生中に一時停止と再開ができるとともに、再生が終わっても頭から再生し直せるようになった。
コード006■サウンドの一時停止と再開に加えて再び再生する処理を定めた
|
旧バージョンのSoundJSライブラリは、一時停止や再開も含めて静的メソッドにサウンドのIDを渡してコントロールした。SoundInstanceオブジェクトの参照をもたなくても済む半面、つくったオブジェクトがクラスに残ったままメモリから除けなかった。SoundJS 0.4.0では、再生し終えたSoundInstanceオブジェクトは、参照をもち続けないかぎりメモリから消されるように改善された(詳しくは、「新CreateJSでSoundJS 0.4.0のメモリの扱いが向上した」参照)。
作成者: 野中文雄
作成日: 2013年3月16日