POPSブログ

CreateJS-画像をロードして表示するを考える(easeljs-0.8)

211

  Category:  javascript2013/04/12 pops 

CreateJS easeljs-0.8用preloadjs-0.6 LoadQueueクラスで、画像をロードして、Bitmap化、addChild()で、Stageに表示するまでを少しまとめてみます。ImageLoaderクラスなども増えて便利になりましたので少し内容を更新しました。色々な方法機能があるものです。

 

CreateJS、で「画像をロードして表示する」を考える。

始めは大変ですが、1つ雌形を作っておけば、全てコピペで使い回し出来ます。CreateJSの多くのメソッドなど使わなくとも「ホンノ少し」で作れるものです。100年かけて覚えれば「健康食品」「医療」いらずで後100年長生き出来ます。


2014/12/13/EaselJSなどバージョンUPされました(easeljs-0.8)。easeljs-0.8用に更新しています。(2015/02/21)


preloadjs-0.6 LoadQueueクラスの詳細については下記の新しい記事も参照ください。

【参照】当方記事: CreateJS easeljs-0.8 LoadQueueクラスでの画像表示の変更など


ワタシも「初心者」で有りまだ短い経験ですが少し判った事のみ記事にします。中には間違いなども在るかも知れませんし、もっと効率良い方法も有るかとも思います。その辺「無理やり御理解」クダサイ。少々説明などが長くなります。


CreateJS画像表示の目次に進む


HTML JS CSS


使用するライブラリの取得

easeljs preloadjs tweenjs soundjs 等は下記の配布元拠りダウンロード出来ます。マニュアル及びサンプルなどが一緒になっています。「CreateJS」 は総称であり、処理に必要なJSのみ使用して構築する様に出来ています。(例えば、TWEEN SOUND関連の処理をしないなら、easeljs preloadjsのみ読み込めば良い)


配布元 : CreateJS createjs.com


ライブラリの読み込み

ダウンロードしたJSを使用する場合。記述は一例です。easeljs-0.8用


<script type="text/javascript" src="js/easeljs-0.8.0.min.js"></script>
<script type="text/javascript" src="js/preloadjs-0.6.0.min.js"></script>
<script type="text/javascript" src="js/tweenjs-0.6.0.min.js"></script>

code.createjs.com利用の場合。easeljs-0.8用


<script type="text/javascript" src="http://code.createjs.com/easeljs-0.8.0.min.js"></script>
<script type="text/javascript" src="http://code.createjs.com/preloadjs-0.6.0.min.js"></script>
<script type="text/javascript" src="http://code.createjs.com/tweenjs-0.6.0.min.js"></script>

重要、バージョン違いでは動かない場合が有りますので必ず合わせて下さい。バージョンアップ毎に色々と変わっているので注意。


HTML (HTML5)


<div id="sample-box" class="radius">
	<canvas id="myCanvas" width="640" height="300"></canvas>
</div>

一応上記のようなCanvas構造の中に画像をロードして表示するのを想定します。必ずCanvasの大きさ width height を記載ください。Canvasの大きさをCSSでの変更は出来ません。


CSS

CSSの記載は任意です。

注意、ステージ(Canvas)に描画するTextはCSSのため「直接描画するText」に限り、外側のHtmlのCSSの影響を受けます。CreateJSコンテナクラスでラップして配置すれば、影響を受けません。


JS (概略)



//xxxxx.js
//グローバルな変数など
var canvasObject;//必要なら
var stage;//これだけでもOK

//manifest
var manifest=[];

//onload後、init実行の指定
onload=init;

//関数init
function init() {
	//ステージを作る他
}
//関数その外必要なものを記載
function xxx() {
	//処理
}
-----------------------------
init実行の指定も色々書き方あり
//onload後
onload=function () {
	init();
};

//スクリプトの最後で
init();

動作が正常なら、記述形式などは自由と思います。全員書き方は異なりますから、適当な人のモノを真似ればよい。


JSの読み込みと実行


<script type="text/javascript" src="js/xxxxx.js"></script>

ワタシの場合は、body内部に記載している。実行は必ず window.onload 後にして下さい。


最初の基本と表示の順序


以下、あくまでも「初心者向け」であり「初心者」であるワタシの僅かな経験に基づくものです。


[ CreateJS画像表示の目次 ]


 

ステージを作る

▲[ 目次 ]

CreateJSでは、必ず最初にステージを作ることになります。色々な処理はステージに対して行われます。特定のCanvasを指定していると考えれば良いでしょう。
作り方は簡単です。下のようにしますがCanvas要素に対し1つのステージです。「Canvas要素が複数」あれば「複数のステージ」を作ることは出来ますが、通常は1つの様です。
以後、このステージに対して画像を貼り付けたり、動かしたりの処理を行うことに成ります。



//グローバルにオブジェクトを作る、名前は随意
var canvasObject;
var stage;

function init() {

	//ステージを作るCanvasを指定
	canvasObject=document.getElementById('myCanvas');
	//名前空間createjsにステージを設定
	stage=new createjs.Stage(canvasObject);

	//その外の処理
}
-----------------------------
簡単にこれでもOKである、最近誰しもこれで済ましている

stage=new createjs.Stage('myCanvas');

ここでの createjs は「名前空間」だそうで、easeljs-0.5 拠り設定され、変数の競合を防止している訳ですネ。


画像表示までの順序は次ぎの様になる。


1. 指定Canvasエレメントにステージを作る。
2. LoadQueueクラスのローダーで画像を読み込む。(ローダーを使用しない方法もある)
3. 画像を扱い易くするため Bitmap 化する。
4. 指定位置に addChild() する。
5. ステージアップデートする。stage.update()の実行


大体の一般的な順序です。


ステージ描画の画像を見ている

ステージに描かれるのはPNG画像です。Canvasエレメント「myCanvas」の中に作られる、Canvasエレメント要素などを統合してTickr設定の時間毎に再描画(stage.update)されるPNG画像を見ている訳です。
ちなみに、Canvasエレメント「myCanvas」のcontext("2d")を得れば、瞬時の画像を取り出せます。
ステージにaddされていないものおよびステージ範囲外に配置されたものは表示されません。


Bitmap()で直接画像を表示する

▲[ 目次 ]

ローダーを使用しないで、createjsのBitmap()クラス処理で「直接画像を表示」する方法です。「AS3」と比較すると単純なので、すこぶる簡単だ!。ここでは、addChild() update()は省略して説明。


● 直接画像を表示 1

ローダーを使用するより簡単なので旨く使い分けると便利である。但し、画像が完全に読み込まれてからでなければ処理出来ないクラスなどあるので注意。単に画像を表示させたい場合に便利。
クロスドメイン画像は表示は可能であるが表示するとは限らない。イベントが機能しなくなったり色々な障害が出るので利用しない方が良い。(地獄をみる事になる.....)


Bitmap(画像URL)で直接画像を表示する場合に加工出来るのは、位置、スケール、角度、透明度、位なものです。



直接Bitmap()に画像URLを書き込む、一番簡単だ、名前は随意
var bitmap=new createjs.Bitmap("images/xxxx.jpg");

クロスドメイン画像は原則禁止、地獄をみる
var bitmap=new createjs.Bitmap("http://papipupepo.com/images/xxxx.jpg");

Bitmap()に画像URLとIDを書き込む
var bitmap=new createjs.Bitmap({src:"images/xxxx.jpg",id:"image1"});

「id」があればその「id名」を指定して操作可能になります。便利な面も有りますがその反面ローダー操作、ファイル判別などが面倒になります。


● 直接画像を表示 2 (preloadjs-0.6)

preloadjs-0.6より新たにImageLoaderクラスが加わりましたので、読み込み判定(complete)して表示出来ます。読み込みに失敗すれば表示しません。エラーの処理は出来ません。
bkloaderはローダーのインスタンス、名前を変えれば複数使える。
イベントを加えれば、event.result値、大きさを取得出来ます。下記に例を示す。


指定のBitmapに画像を流し込むには下記の様になります。(階層構造重ね順が変わりません)



//画像ローダークラスでチェック
var bkloader=new createjs.ImageLoader("images/xxxx.jpg",false);
bkloader.addEventListener("complete",function() {
	var bitmap=new createjs.Bitmap("images/xxxx.jpg");
});
bkloader.load();

//イベントを加えれば画像ローダークラスで画像result値を取得
var bkloader=new createjs.ImageLoader("images/xxxx.jpg",false);
bkloader.addEventListener("complete",function(event) {
	var bitmap=new createjs.Bitmap(event.result);
	//同じドメイン画像ならば大きさ取得も可
	横幅=event.result.width;
	高さ=event.result.height;
});
bkloader.load();

//指定のBitmapに画像を流し込む
var back_image=new createjs.Bitmap();//空画像
stage.addChild(back_image);

//読み込み
var bkloader=new createjs.ImageLoader("images/xxxx.jpg",false);
bkloader.addEventListener("complete",function(event) {
	back_image.image=new createjs.Bitmap(event.result).image;
});
bkloader.load();

● 番外、指定の空のグラフイックに画像を流し込む

この場合は必ず空のShape()を配置しておきます。
グラフイックなら、着色したbeginFill("#FFFFFF")または、beginFill("")ならエラーにはなりません。
複数の空のShape()の場合は配置のためのコンテナを配置して置き、あとでShape()をaddChildします。

空のgraphics.beginBitmapFill()を配置すると重大なエラーに成る場合がありますから注意ください。



//指定の空Shape()に画像を流し込む
var back_image=new createjs.Shape();//空Shapeはエラーにならない
stage.addChild(back_image);

//読み込み
var bkloader=new createjs.ImageLoader("images/xxxx.jpg",false);
bkloader.addEventListener("complete",function(event) {

	var g=new.createjs.Graphics();
	g.beginBitmapFill(event.result).drawRoundRect(0,0,100,50,5);
	back_image.graphics=g;
});
bkloader.load();

easeljs-0.8では、beginBitmapFill() にクロスドメイン画像を絶対に入れない事。再起不能な地獄を見ます。


● 直接画像を表示 3

早めに、new Image()を実行して、javascriptの非同期処理を組み合わせる(onload関数を実行)。但し画像を読み込まないと以後実行しない難点がある。ほとんど大丈夫と思いますが、、、
簡単なサンプル表示には向いているだろう。

easeljs-0.8では、ImageLoaderクラスで画像をチェックできます。



var stage;

function init() {

	//javascriptのonloadが成功しないとこのinit()は実行できない
	stage=new createjs.Stage('myCanvas');
	//Bitmap()に代入表示する
	var bitmap=new createjs.Bitmap(ximage);
	stage.addChild(bitmap);
	//Canvasを更新
	stage.update();
	.
	.
}
var ximage=new Image();
ximage.onload=function() {
	init();
}
ximage.src="images/xxxx.jpg";

外部ドメイン(クロスドメイン)から読み込む画像は、原則禁止です。どうしても読み込まざる理由があればイベントなどの不都合の起きた所を修正せねば成らない。かなり大変な作業になります。


レーヤー代わりにコンテナを配置する

レーヤーは有りませんので、代わりにコンテナを配置すると階層を管理できます。
単に順番にstage.addChild(部材)では旨く階層を管理出来ません。重ね順は変更できますが、思わぬ所で重ね順が違って困る場合があります。
必要なコンテナを先にステージに配置しておき、画像などロードしてから、addChild(部材)すれば良い。
色々とやってみると、表舞台には無いがコンテナの役割、コンテナのみ出来る機能などが後々に判ってくると思います。


var stage;
var container01,container02,container03;

function init() {

	//stage
	stage=new createjs.Stage('myCanvas');

	//コンテナ配置階層確保
	container01=new createjs.Container();
	container02=new createjs.Container();
	container03=new createjs.Container();
	stage.addChild(container01,container02,container03);
	.
	.
}
-----------------------------
後で、コンテナに部材を入れる

var bitmap=new createjs.Bitmap(画像result値);
container01.addChild(bitmap);

コンテナの中に部材が複数あろうと削除も楽です

container01.removeAllChildren();

画像をローダーでロードする

▲[ 目次 ]

画像をロードするするには、preloadjs のローダーを使用します。事前に、preloadjs を読み込んでおく。
画像を加工処理などする時には「完全に読み込み完了」が条件ですから、ローダーを使用しないと旨く処理出来ない場合が多い。


LoadQueueクラスのローダーを使用して画像を読み込む


easeljs-0.8用、preloadjs-0.6

新しいバージョン preloadjs-0.6 は以前のものとは完全に違います。前の設定でもほとんど可動すると思いますが、基本的にXHR処理になります。
通常は、クロスドメイン用のクロスオリジン指定を考慮しなくとも良いと思います。

LoadQueue(true)が標準になります


LoadQueue(false)は、HTMLタグベースの読み込みを実行します。エラー処理が無く、読み込み失敗で停止します。

LoadQueue(true)は、HTMLタグベースの読み込みを実行して、失敗すればXHRベースの読み込みを実行。


通常の同じドメインの読み込みでは、HTMLタグベース、XHRベースなどの方式を意識する必要は有りません。エラー処理をするかしないかの区別になります。



LoadQueue(XHRの選定,ファイルまでのパス,クロスオリジン)

//Loaderを作る
loader=new createjs.LoadQueue(true);
-----------------------------
上記設定は下記と同じです
loader=new createjs.LoadQueue(true,"","Anonymous");


//エラー処理を実行する
loader=new createjs.LoadQueue(true);
loader=new createjs.LoadQueue(true,"","");

//エラー処理を実行しない
loader=new createjs.LoadQueue(false);
loader=new createjs.LoadQueue(false,"","");

個人的には従来の easeljs-0.7.1記述のJS は、LoadQueue(true) に変更したほうが良いと思います。


easeljs-0.7用、preloadjs-0.4、でも基本的に動作します。

古いバージョンは、preloadjs LoadQueue(false) と false 指定です。
ローダーを使用する場合は、preloadjs を事前に読み込んでおきます。


easeljs-0.8でもエラー処理をしないだけで、特殊な場合を除き基本的には動作はします。


●標準のLoader設定

グローバルな場合は先にローダーを宣言し用意しておく 名前は随意で loader queue 等使用される、グローバルな方が便利なことが多い。


var loader;//グローバル

function loadimage () {

	//Loaderを作る
	loader=new createjs.LoadQueue(false);
	//Listener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);

	//その外の設定
}

idで操作するときは、loaderをグローバルにしておくほうが良い
-----------------------------
ローカルなLoaderを作る、名前は随意、EventListener削除の際は event.target で処理可能

function loadimage () {

	//Loaderを作る
	var loader=new createjs.LoadQueue(false);
	//Listener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);

	//その外の設定
}
-----------------------------
Listenerを設定すると
1つのファイルが読み込まれる毎にfileloadイベントが発生する
全てのファイルが読み込まれるとcompleteイベントが発生する

loader.addEventListener("fileload",ハンドル名);
loader.addEventListener("complete",ハンドル名);
エラー処理が必要なら
loader.addEventListener("error",ハンドル名);

ハンドル名は随意です

1ファイルの読み込み、複数ファイルの読み込みの違い

loadFile()、loadManifest()、共に初期状態は「ロード実行」true の状態です。

1ファイル、複数ファイルの読み込みは少々違う。それぞれ命令がある。同時に使用する事も可能。

● 1ファイル読み込みは、loadFile(file)を使用する。(ロードの実行を伴う)


1ファイルを設定、共に同じことです
var file={src:"images/xxx.jpg",id:"image1"};
loader.loadFile(file);
または
loader.loadFile({src:"images/xxx.jpg",id:"image1"});
-----------------------------
1ファイルを複数設定もできる
var file={src:"images/xxx.jpg",id:"image1"};
loader.loadFile(file);
var file2={src:"images/xxx.jpg",id:"image2"};
loader.loadFile(file2);
-----------------------------
注意、1ファイルの場合、下でも読み込むが「id」がないので「分類区別」が難しくなる
loader.loadFile("images/xxx.jpg");

● 複数ファイル読み込みは、loadManifest(manifest)を使用する。(ロードの実行を伴う)

複数ファイル登録用の、manifest リストが必要になります。(リスト名はmanifest以外でも可能)


複数ファイル
登録用 manifest はグローバルで、事前に登録しておく
var manifest=[
	{src:"images/xxx.jpg",id:"photo1"},
	{src:"images/xxx.jpg",id:"photo2"}
];

loader.loadManifest(manifest);


下2つは同じ、「ロードの実行」設定
loader.loadFile(file);
loader.loadFile(file,true);

下2つは同じ、「ロードの実行」設定
loader.loadManifest(manifest);
loader.loadManifest(manifest,true);

● 任意の位置で、ロードの実行を行う、load()

通常loader.load()は使用されない。上記、loadFile(file)、loadManifest(manifest)に「ロードの実行」も含まれている。


falseの設定でロードの実行をさせない、true は簡略できるので、初期値は true 設定である

意図的に false を設定する
loader.loadFile(file,false);
loader.loadManifest(manifest,false);

任意の段階でロードの実行をさせる
loader.load();

アルバムなどで、1枚ずつ指定の画像を表示する場合、通常は繰り返しloaderを使用することになるが、load()を旨く利用すれば少し効率が良くなるのかナ。(EventListenerなどの上書きが無い分....)


● manifestの登録

複数の画像、種類の違うファイルを、manifestリストに登録して loadManifest(manifest) で読み出しが可能です。
「AS3」等でも複数の場合はリストなどに登録(機能を作る)して行いますので同じです。preloadjsのLoadQueueクラスでは種類の違うファイルも(画像、サウンド、JS、、など)1つのローダーで読み込みできます。

新しい、preloadjs-0.6では、読み込むファイル別の「個別ローダークラス」が用意されましたので、読み込む時点で「判別読み込み」が出来ます。
つまり、manifestを利用しないで分離したほうが便利になります。

ImageLoaderクラスなどを参照



登録用manifestはグローバルで、事前に登録しておく
var manifest=[
	{src:"sound/xxxxx.mp3",id:"sound"},
	{src:"images/xxx.jpg",id:"photo1"},
	{src:"images/xxx.jpg",id:"photo2"}
];

● 一番応用の利く形 (manifestリストあり)

組み合わせ次第で色々な書き方があってどれが良いか判らないので、、下のようにすれば応用が効くのではと思います。id名は任意です。色々と試した結果ですがよく見ると、マニュアル「PreloadJS Module Example」と同じ形式です。


var image_max;//画像数
var loader;//ローダー
var assets=[];//画像データ容器
//必要があれば追加できる、常にmanifestを利用する
var manifest=[
{src:"images/xxx.jpg",id:"PHOTO1"},
{src:"images/xxx.jpg",id:"PHOTO2"}
];

function imageload() {
	//グローバルLoader
	loader=new createjs.LoadQueue(false);
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);

	//必要があればloadFile()も追加できる
	//loader.loadFile({src:"images/xxx.jpg",id:"parts1"});
	//loader.loadFile({src:"images/xxx.jpg",id:"parts2"});

	//1つでもloadManifestで実行出来ます
	loader.loadManifest(manifest);
}
//onfileload
function fileload (event) {
	//エラー無しの画像をassets容器に保存、必ずresult値のこと
	//分類が必要なら追加で書く
	assets.push(event.result);

}
//oncomplete
function complete (event) {
	//loader Listener削除、loaderはグローバル
	loader.removeEventListener("fileload",fileload);
	loader.removeEventListener("complete",complete);

	//ロードに成功した画像数計算
	image_max=assets.length;

	//その外の処理
}

この形を旨く使用したほうが良いと思う。複数画像は、assets.push()で処理しているからエラーがあっても大丈夫である。画像を保存容器の番号で扱うか、id名で扱うかの違いである。ワタシの場合は「番号」で扱う。
「id」値を別「配列容器」に保存して、使用する人もいる。これは自由である。


タイプ指定はpreloadjs-0.6より AbstractLoaderクラス継承で、createjs.AbstractLoader 推奨になります。

タイプ指定、以前は createjs LoadQueueでした。preloadjs-0.6ではまだ使えます。


//画像manifestリスト
var manifest=[
	{id:0,src:"/main/images/flight01.jpg",type:createjs.AbstractLoader.IMAGE},
	{id:1,src:"/main/images/flight02.jpg",type:createjs.AbstractLoader.IMAGE},

	略す
];
//Loaderを作る/エラー対処ならtrue設定
loader=new createjs.LoadQueue(true);
.
.
//Manifestを使用、manifest読み込み開始
loader.loadManifest(manifest);

●1枚の画像を読み込む (manifestリストあり)

1枚の画像を読み込む、loadFile()を使用してみます。

リスト中、src:"/main/images/toyota_car10.jpg"、などは当方の画像パスです。


var imageBox;
var xImage;
//画像manifestリスト
var manifest={src:"/main/images/toyota_car10.jpg",id:"PHOTO1"};

function imageload() {
	//Loaderを作る
	var loader=new createjs.LoadQueue(false);
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//loader.addEventListener("error",loaderror);
	loader.loadFile(manifest);
}

//画像読み込み完了(fileload)
function fileload (event) {
	//resultを保存
	xImage=(event.result);
}
-------------------------------
loader.loadFile(manifest);
を
loader.loadManifest(manifest);
としても同じこと

loadManifest() は () の中の「配列変数」を読み出し登録リスト「manifest」とするそうです。書き方は「連想配列」です。


●1枚の画像を読み込む (manifestリスト無し)


function imageload() {
	var loader=new createjs.LoadQueue(false);
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//1枚の画像を読込
	loader.loadFile('images/xxx.jpg');
}
-----------------------------
上と同じようなもの
function imageload() {
	var loader=new createjs.LoadQueue(false);
	var file={src:"images/xxx.jpg",id:"image1"};
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//1枚の画像を読込
	loader.loadFile(file);
}

● 複数画像を一括に読み込む


var assets=[];
var manifest=[
{src:"/main/images/toyota_car10.jpg",id:"PHOTO1"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO2"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO3"}
];

function imageload() {
	//Loaderを作る
	var loader=new createjs.LoadQueue(false);
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//Manifestを使用、manifest読み込み開始
	loader.loadManifest(manifest);
}

//各画像読み込み完了(fileload)
function fileload (event) {
	var type=event.item.type;
	//画像のみ選別
	if (createjs.LoadQueue.IMAGE == type) {
		//エラー無しの画像をassets容器に保存
		assets.push(event.result);
	}
}

注意、push()の際は必ず、event.result で取り出すこと。(idのみ保存する方法もあるが、、)


● 複数画像を一括に読み込むと、個別に画像をロードするの組み合わせ

同じloaderである、loader.loadFile()とすれば同じ、fileload、completeが発生するので、選別を工夫する。
manifestと同じく、src、id を記載したほうがあとで、分類し易い。


manifest の画像と使用目的、種類、パス、が違うので分離して書くとかの事情がある場合です。選別は同じ fileload で行う事になります。出来れば manifest にマトメタ方が賢明と思います。(easeljs-0.8以前の考え方)


easeljs-0.8からは preloadjs-0.6 LoadQueueクラス が大幅に変更になり、個別ローダークラスがありますので、manifestより分離出来るものは都合の良い時点で読み込むなどの工夫をした方が効率くなると思います。
fileloadのリスナーでの分類も簡単になりますし、面倒な分類等しなくとも良いように簡略化も出来ます。



var assets=[];
var manifest=[
{src:"/main/images/toyota_car10.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO"}
];

function imageload() {
	//Loaderを作る
	var loader=new createjs.LoadQueue(false);
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);

	//1枚画像読み込みをloadFile()で追加する
	loader.loadFile({src:'images/xxx.jpg',id:"image1"});

	//Manifestを使用、manifestで複数画像読み込み開始
	loader.loadManifest(manifest);
}

//各画像読み込み完了(fileload)
function fileload (event) {
	var id=event.item.id;
	//画像選別
	if (id == 'image1') {
		//処理
	}
	if (id == 'PHOTO') {
		//エラー無しの画像をassets容器に保存
		assets.push(event.result);
	}
}

progressを設定しても、loadFile()で追加したものはキッチリ処理されます。


上記の様に、push()を使えば読み込み画像数の計算は楽


読み込み画像数=assets.length;

assets の数は assets.length で取得できる。その外は event.item.id で判別できる。後は個人の工夫で対処する。読み込みファイルの種類が多いと大変です。バージョンアップ毎に改良されるのを期待しましょう。
他の人がどのように処理しているか調べるのも、1つの手法です。


● manifest の名前を変えたい

manifestは配列変数名ですから自由な名前で使用は出来ますが、manifestの名前を使用したほうが間違いが起き難いと思います。政治、政党関係の方は、mamoreruKouyaku としたほうがウソでも世間テイが良い。



var xxxfile=[
{src:"/main/images/toyota_car10.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO"}
];

//Manifestを使用、指定のリスト名(manifest以外の変数名)で使用する
loader.loadManifest(xxxfile);

注意、loader.loadManifest()は同じです。複数読み込みですから必ず loadManifestクラス指定です。loader.xxxfile(xxxfile)とは書きません。


● 外部ファイルとしてのmanifestリストを読み込む

preloadjs-0.6より、manifestリストの形式で記載した「jsonファイル」を読み込み実行出来る様に成りました。基本JSを変更せずに更新出来ることに成ります。マニュアルより転載



loader.loadManifest("path/to/manifest.json");
loader.loadManifest({src:"manifest.json", type:"manifest"});

 

休憩。ポップコーン、赤まむしドリンク、等は左側通路「売店」にてお買い求めください。後編上映は15分後です

mendou da nasshi-

非公認キャラクターを非公認で使用しています

 

後編の上映開始です


PreloadJSクラスの定数の表


ローダーは色々な種類のファイルを扱います。manifestなどの記載に基づき、ローダーがファイルの種類に応じて「読み込みを設定」します。その時の「設定」がクラスの定数の「値」で知る事ができます。fileload で取得出来る、item のプロパティと「比較」することで分類して使用するのだそうです。 このほか少し増えていますが、マニュアルなど参照ください。(余り使わない)

PreloadJSクラスの定数 ファイル形式 おもな拡張子
CSS css CSS .css
IMAGE image 画像 .png/.gif/.jpg
JAVASCRIPT javascript JavaScript .js
JSON json JSON .json
SOUND sound サウンド .mp3/.ogg/.wav
SVG svg SVG .svg
TEXT text テキスト .txt
XML xml XML .xml

createjs LoadQueueの定数とその値、取得例、createjs.LoadQueue.SOUND、使用例は下記参照

preloadjs-0.6よりAbstractLoaderクラス継承で、createjs LoadQueue は createjs.AbstractLoader 推奨になります。

 

fileload で取得出来る、item のプロパティの表

ローダーの中の情報です。読み込んだファイル数分あることになります。

プロパティ 値等 その外
item.type image、javascript、css など ファイルの種類
item.text jpg などドットを含まない拡張子 拡張子
item.id loadFile()登録時に指定したid 登録時に記載のid
item.src loadFile()登録時に指定したsrc 登録時に指定したURL・パス
item.tag 画像ならimg、CSSならstyle、JSならscript 読み込んだファイルを扱えるtag名

fileload で取得する、event.item.type は、上記の「値」になる。使用例は下記参照

上記の表は 「fumiononaka.com : FN1205002テクニカルノート」「nakajmgtech.blogspot.jp : CreateJS勉強会」 の記事を参考にしました

 

● fileload処理 (1つのファイル読み込み完了毎にeventが発生する)

複数のファイルなどをローダー処理出来ますが、EventListener は1つですから、fileload での分類処理が必要になります。後で処理し易いようにしたり、サウンドデータを分別シタリ。使用目的に拠り配列に代入したりの処理を行います。

fileloadハンドラでは「event.item」情報が取得できます。上記「item のプロパティの表」参照。


1. id で区分する。
2. item.type で区分する。(LoadQueueが持つ定数と比較したりする)
3. 「id 名」を工夫したり、独自の区分方法を考える。
4. 適当なプロパティを追加して利用する。(使用していない名前なら使える)



event.item はmanifestの情報です

function fileload (event) {
	//処理を書く
}

通常は同じタイプの画像が複数登録なっているので区分などはしない場合が多い。一番簡単である。


function fileload (event) {
	//エラー以外の画像を保存
	assets.push(event.result);
}

複数の画像、または違う種類のファイルをmanifestに記載している場合など、状況に応じて分類保存するなどの処理が必要です。manifestの「id」を旨く使用しても良いが、この辺は使用者の設計に依存します。



LoadQueueが持つ定数と比較して分類、switch文使用

function fileload (event) {
	var type=event.item.type;
	switch(type) {
		case "sound":
			//処理
		break;
		case "image":
			//処理
		break;
	}
}
-------------------------
AbstractLoader に変更になります

LoadQueueが持つ定数と比較して分類、if文使用

function fileload (event) {
	var type=event.item.type;
	if (createjs.LoadQueue.SOUND == type) {
		//処理
	}
	if (createjs.LoadQueue.IMAGE == type) {
		//処理
	}
}
------------------------
manifestにデータを追加して判別に使用する、但し動作確認のこと
単なる配列であるから preloadjs で予約されてる、src id  type ext tag data 以外の名前は使用できる
名前は随意、エラーなどなく認識するので問題は無いと「オモウ」

var assets=[];
var manifest=[
{src:"/main/images/toyota_car10.jpg",id:"PHOTO1",group:"parts"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO2",group:"slide"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO3",group:"slide"}
];

//画像を使用目的別に分類、勝手にmanifestにgroupを入れて判定
function fileload (event) {
	var group=event.item.group;
	if (group == 'parts') {
		//処理
	}
	if (group == 'slide') {
		assets.push(event.result);
	}
}

分別の方法は考えれば色々あると思う。


● preloadjs-0.6、タイプでの判別がcreatejs LoadQueueより createjs.AbstractLoader に変更になります。

タイプ指定、以前は LoadQueue でした。preloadjs-0.6ではまだ使えます。


タイプ指定の変更があります、非推奨
createjs.LoadQueue.IMAGE

新しいタイプ指定
createjs.AbstractLoader.IMAGE


LoadQueueが持つ定数と比較して分類、if文使用

function fileload (event) {
	var type=event.item.type;
	if (createjs.AbstractLoader.SOUND == type) {
		//処理
	}
	if (createjs.AbstractLoader.IMAGE == type) {
		//処理
	}
}

● complete処理、(全ての読み込み完了)

loader Listener削除の処理などが主です。面倒なので削除処理しない方が多い。厳密には削除したほうがメモリー効率上良いそうだ。(Listener登録も面倒なのに、削除しろとはマタマタ面倒!)

completeハンドラでは「event.target」情報が取得出来ます。但し「event.item」情報は取得出来ませんので注意下さい。



event.target はloaderです

//全ての画像読み込み完了(complete)
function complete (event) {

	//loader Listener削除
	event.target.removeEventListener("fileload",fileload);
	event.target.removeEventListener("complete",complete);

	//その外の処理
}
---------------------------
loaderがグローバルな場合は、

var loader;
//全ての画像読み込み完了(complete)
function complete (event) {

	//loader Listener削除
	loader.removeEventListener("fileload",fileload);
	loader.removeEventListener("complete",complete);

	//その外の処理
}
画像等をid名で操作する場合は、loaderがグローバルな方が便利でしょう

● error処理

error処理も出来ますが、面倒ですから、ほとんど記載していることは無いようです。

errorハンドラでは、event.item 情報が取得できますのでファイル毎の処置が可能です。



function loaderror (event) {
	//必要なら記載
}

fileerror、(通常処理では考慮の必要は無い)
preloadjs-0.6で追加になった「エラータイプ」です。manifest利用で「XHR処理のエラー」で途中停止した場合にスキップしてmanifest処理を継続させる役目を持ちます。
「fileload」「error」のリスナーもスキップして実行しません。通常の同じドメイン処理では「XHR処理のエラー」はほぼ無いでしょう。fileerrorハンドラ設定の場合、errorハンドラは設定出来ません。(どちらか1つのようです)

fileerrorハンドラの中は何も書きませんが、無ければmanifest処理は停止します。現在、書いても何も実行しません。



loader.addEventListener("fileerror",fileerror);

function fileerror (event) {
	//何も書かない
}

代替画像を挿入する
何らかの画像がなければエラーになるような画像加工をしている場合などに、着色Canvasエレメントなどが代用に使用できます。工夫次第ではグラフイックを描画したりも可能と思います。Canvasエレメントは画像と同様なものです。

一番危険なのは、beginBitmapFill(画像)、処理で画像が無ければブラウザによっては重大エラーになりJSが停止の恐れ有り。代替画像があればこれを防止できる。


function loaderror (event) {
	//100x80白色、代替画像を挿入
	assets.push(createColorCanvas(100,80,"#FFFFFF"));

}

//色付きcanvasを作る
function createColorCanvas (w,h,c) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);
	return canvas;
}

EventListener()について

▲[ 目次 ]

何らかのEventが発生する仕組みを利用する場合は全てに addEventListener() を設定しなければなりません。書式は全部共通ですので簡単ですが。記述して、不要になったらあとで削除しなければならないのが面倒です。


最近は、jQueryと同じような、on() off() 形式のリスナー設定が好まれているようです。


addEventListener()形式のリスナー


Listenerイベントハンドラ書式

対象インスタンス.addEventListener("イベントの種類",イベントハンドラ名);

[設定例]
loader.addEventListener("complete",complete);
[削除例]
loader.removeEventListener("complete",complete);
-----------------------------
以前は、loaderの「プロパティ」の「complete関数」を直接指定出来たのですこぶる簡単でした
[例]
loader.addEventListener("complete",complete); と書く、不要になったら削除
または
loader.addEventListener("complete",function(event) {
	//処理
});

[例]
bottun.addEventListener("click",clickhandler);
または
bottun.addEventListener("click",function(event) {
	//処理
});
-----------------------------
easeljs-0.6用だから現在はない
以前は、loaderの「プロパティ」の「complete関数」を直接指定出来たのですこぶる簡単でした
loader.onComplete=complete; はだめ「現在無し」
bottun.onClick=clickhandler; はだめ「現在無し」
-----------------------------
面倒だがAS3拠りはましだと考えましょう

on() off() 形式のリスナー

簡単なことと、addEventListener()より便利なために、最近は多用されています。thisの使用が出来る事と一時的にoffに出来るのが最大の利点です。
1. on()でリスナーを有効に、無ければ作ります。
2. off()でリスナーを一時停止。
3. 現在ほとんどのイベントでon()の使用が出来る。(マニュアル参照のこと)



オブジェクト.on(イベントの種類,リスナー関数,スコープ,1回かぎりか,渡す値,キャプチャ)

コールバック関数の中で使用されている場合、this キーワードはリスナーオブジェクトを参照します
1回かぎりかは、通常は繰り返し使用しますからfalseです

インスタンスにリスナーの設定と削除


ハンドル名は任意
//on
bottun.on("click",clickhandler,this);

//off
bottun.off("click",clickhandler,this);

//削除
bottun.removeEventListener("click",clickhandler);

インスタンスに設定例


bottun.on("click",clickhandler,this,false,1);

function clickhandler(event,no) {
	//この例ではno は1の値
	//this はリスナーオブジェクトbottunを参照
}

ローダーにリスナーの設定と削除

ローダーの場合は渡す引数など受け取らない場合もあるので注意が必要です。(個別ローダー、ImageLoaderクラスなどと組み合わせる場合など)
個別ローダー、ImageLoaderクラスなどのイベントタイプは complete だけの場合が多いので注意。


ハンドル名は任意
ローダー引数は this 位が無難と思う
//on
loader.on("complete",complete,this);
loader.on("fileload",fileload,this);
loader.on("error",loaderror,this);

//off
loader.off("complete",complete,this);
loader.off("fileload",fileload,this);
loader.off("error",loaderror,this);

//削除
loader.removeEventListener("complete",complete,this);
loader.removeEventListener("fileload",fileload,this);
loader.removeEventListener("error",loaderror,this);

マニュアル、「各Classのイベント」など参照。


ローダー画像情報を Bitmap() 処理する

▲[ 目次 ]

画像をロードしてもそのままでは表示できません。表示前にBitmap()処理をします。 imageBoxはグローバルでも良い。以下は、グローバルなxImageに保存しているresultを処理します。

Bitmap()は画像をCanvasに表示させるための処理を行うクラスです。Canvasに表示する操作は単純ですし、AS3を考えれば楽なものです。

注意、ここで xImage 又は 配列assets の保存情報は「URL」ではなく「HTMLエレメントオブジェクト」情報です。


● グローバルなxImageに保存しているresultを処理


ハンドラ fileload で xImage に「event.result」の値があるとして

//DRAW
function draw() {

	//resultの保存値をBitmap化、xImageは「event.result」の値
	var imageBox=new createjs.Bitmap(xImage);

	//ステージリストに追加(addChild)、まだリストに追加されただけ
	stage.addChild(imageBox);

	//Canvasを更新、これで初めて表示される
	stage.update();

}

● 配列assetsに保存しているresultを処理 (push()で配列に入れているので、画像を取得出来たものだけの情報だ)
スライドショウなどで、複数画像を扱う場合は、番号で管理したほうが便利だ。
目的、状況により効率的な方法を取れば良いと思う。個人的に結構違いが有りますから、これが一番とは言い難い。


ハンドラ fileload で assets.push(event.result)で「event.result」の値があるとして

//DRAW
function draw() {

	//配列の番号を指定
	var no=0;
	//resultの保存値をBitmap化
	var imageBox=new createjs.Bitmap(assets[no]);

	//ステージリストに追加(addChild)、まだリストに追加されただけ
	stage.addChild(imageBox);

	//Canvasを更新、これで初めて表示される
	stage.update();

}

Canvasを更新のupdate()

Bitmap() 画像などを addChild() してもまだ表示はされない。該当のCanvasを更新処理 stage.update() して初めて表示される。update()はステージ単位での更新になります。その都度update()するのが繁雑である場合は、Ticker機能でupdate()すれば手間が省けます。


	//Canvasを更新、これで初めて表示される
	stage.update();

画像情報、保存result値のBitmap()化の方法

「createjsのローダー」で読み込み、「result値」を利用すれば「createjsでの処理」が旨く出来るようになっている訳です。もしも「id」値が取得出来なければ「ローダー」で読み込み失敗しています。

● assets.push(event.result)で保存している場合は、「番号」で取り出せば間違いなく取得できる。



配列assets保存の1番目を取り出す
var no=0;
var imageBox=new createjs.Bitmap(assets[no]);

配列保存の際、assets.push(event.result)で保存していれば、「読み込み失敗」のデータは保存されないので、間違いなくデータを取得出来る利点がある。


ローダーのidでBitmap()化の方法

ローダー登録の id:"PHOTO1" を使用する場合は、loaderがグローバルでローダー情報を保持しているなら、取り出せるが必ずあるとは限らない。(読み込みに失敗していれば無い)

連続する、スライドショウなどの画像表示には工夫をしないと旨く情報を取り出せない。fileload処理での分類方法が重要です。コンテンツの設計次第では「id」で処理した方が良い時も有りますから、この辺は臨機応変に対処します。



manifestの登録を以下とした場合
var manifest=[
{src:"/main/images/toyota_car10.jpg",id:"PHOTO1"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO2"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO3"}
];

直接id名でBitmap()化
var imageBox=new createjs.Bitmap(loader.getResult("PHOTO1");
-----------------------------
fileload処理でidを保存しているなら
function fileload (event) {

	var id=event.item.id;
	//idを保存
	assets.push(id);

}

idを保存しても可能だ
var no=0;
var imageBox=new createjs.Bitmap(loader.getResult(assets[no]);

「id」で取り出せない場合は、読み込みに失敗していることになる。事前に「id」があるか調べて処理することも重要である。(同じドメインならほとんど例外なく読み出せます、ほとんどはURLなどの記載のマチガイ)


指定の場所、位置に addChild() 配置する

▲[ 目次 ]

上でも少し言及していますが、ローダーの画像情報を元にBitmap()化して、指定の場所、位置に addChild() 配置することになります。この辺は「AS3」の形式と同じです。

下記では、画像配置のコンテナ、imageContainer を作りその中に画像を入れるようにしています。重ね順を固定するレーヤーの役目に使用しています。コンテナですから移動なども出来ますのでワタシの場合はこの形式にしています。



//ステージインスタンス
var stage;
//コンテナインスタンス
var imageContainer;
//画像容器インスタンス
var imageBox;

//init
function init() {
	ステージを設定、コンテナ配置
	stage=new createjs.Stage('myCanvas');
	//コンテナを作る
	imageContainer=new createjs.Container();
	//コンテナは位置指定がないから原点 0 0 である
	stage.addChild(imageContainer);

	途中略
}

//DRAW
function draw() {
	//ローダー処理は略す

	var no=0;
	//resultの保存値をBitmap化、imageContainer、imageBoxはグローバル
	imageBox=new createjs.Bitmap(assets[no]);
	//位置指定
	imageBox.x=100;
	imageBox.y=100;

	//ステージリストに追加(addChild)、まだリストに追加されただけ
	//ここでは、事前に作ってあるコンテナの中に収容した
	imageContainer.addChild(imageBox);

	//Canvasを更新、これで初めて表示される
	stage.update();

}
//initに進む
onload=init;
-----------------------------
注意
stage.imageContainer.addChild(imageBox); とは書かない、エラーになる
また
stage.addChild(imageBox); なら、コンテナの上の層になる
また
addChild(imageBox); とは書かない、親の指定が無いのでエラーになる
-----------------------------
親になるインスタンス.addChild(子になるインスタンス); の書式になる

現在、addChild 出来るのは(通称、親インスタンスになれるのは)、Stageクラス、Containerクラス、MovieClipクラス、のみのようです。


● 複数の子インスタンスを 一度に、addChild() する

マニュアル説明には、複数の子インスタンスを 一度に、addChild() 出来ると書いてあります。ボタンを作り配置する時に用いられています。マア便利ですが、グラフィックを収容するshapeクラスにaddChild()機能が無いことが要因でしょうか?。


マニュアルでの addChild 例の記載
container.addChild(bitmapInstance, shapeInstance);

親になるインスタンス.addChild(子1,子2,子3, ......); の書式になる

ボタンインスタンス.addChild(shapeインスタンス,textインスタンス);
実は、ボタンインスタンスはコンテナで出来ている

「ボタン」についても別ページで述べる。ここでは略す。


● 指定の場所から、removeChild() 削除する

削除するには、removeChild()で簡単に削除できる、但しリストから削除されただけなので、Canvasを更新してやらないと消えないので注意。上の例で画像を削除するには、
また addChildAt()、removeChildAt()、を使用しても良い。「AS3」と同じである。



//指定のインスタンスを削除
removeChild(imageBox);
//指定の親インスタンスの中の子インスタンスを全て削除
imageContainer.removeAllChildren();
//コンテナごと削除すれば、コンテナと中の画像もなくなる
removeChild(imageContainer);

//Canvasを更新、これで初めて表示がなくなる
stage.update();

addChildAt()、removeChildAt()は簡単だが、場合によっては効率が悪い、複雑な重ね順のコンテンツの場合は重ね順が変わらない様注意しなければならない。


● 表示、非表示の切り替えで一旦消す

削除しないで、表示、非表示の切り替えで一旦けす事も出来ます。これもCanvasを更新(stage.update)してやらないと消えないので注意。Loadingなどを「表示、非表示の切り替え」する場合に便利である。


//指定のインスタンスを一旦けす
imageBox.visible=false;

//Canvasを更新
stage.update();

//反対に非表示のものを、表示するなら
imageBox.visible=true;

//Canvasを更新
stage.update();

必要であれば、付随の処理をする

▲[ 目次 ]

付随の処理などは色々とあるが、かなり長くなるので、別ページで書く事にする。ここでは簡単に、Tickar機能を付け加える。stage.update()用のTickarは1つのみにして下さい。複数のtickイベントを発せられるとマシンは狂います。
簡単に言えば「AS」の enterFrameと同等である、タイムライン機能であるそうだ!。便利だ!。


1. しかるべきスクリプトの位置で、createjs.Ticker.addListener()で自動的にenterFrame機能がwindowに作られるそうな。
2. このとき自動でtickイベントが発信されるので、受ける関数を記載する。関数名を指定して複数設定も可能。
3. 1秒毎の処理フレーム数、「FPS」も指定できる。(当方こちら使用)
4. Ticker.timingModeを利用して1秒毎の処理フレーム数を決める。「FPS」より正確なそうだ。
5. 上では、その都度、stage.update()しているので面倒だ。Tickarに任せれば省略可能である。
6. マチガイなど無くともTickerが機能しない場合もある。(動的にstage.update()を実行すれば描画する)


● ステージupdate()用Tickar機能を設定する


//Ticker設定
createjs.Ticker.setFPS(30);
createjs.Ticker.addListener(window);
//ステージなら
createjs.Ticker.addListener(stage)

Ticker設定のイベントを処理するtick()を作る、ここではTickerのハンドル名を指定して
いないので必ず関数は、tick()とする、自動で処理されるのは便利だが困る事もある

stage.update()用のTickerは1つだけにする
//tick
function tick() {
	stage.update();
}

注意としては、Ticker複数設定の場合は、旨く名前、場所を指定しないと、上書きされるので注意のこと。詳細は別ページで述べる。


● マチガイなど無くともTickerが機能しない場合もある。

設定などに不備は無いのに、グラフイックなど一部修正した場合などに「稀にTickerが機能しなく」描画されないなどの不具合が出る事がある。
グラフイック修正後、動的に stage.update() をすれば動作、正しく描画される。



	//rollover
	bottun.addEventListener("rollover",function(){

		グラフイックなど一部修正、Tickerが機能しないこともある
		stage.update();
	});

Ticker.timingModeプロパティについては下記参照ください。

【参考】HTML5:テクニカルノート記事: EaselJS 0.7.0のTickerクラスでrequestAnimationFrameのAPIを使う - Ticker.timingModeプロパティ

結構最初はこれで泣かされたゼ、詳細は専門家の「fumiononaka.com HTML5:テクニカルノート記事」「gihyo.jp記事」等を参考にしてください。下記に参照リンクがあります。



以下の他サイトの記事などを参考にさせて戴きました。

【参考】HTML5:テクニカルノート記事: PreloadJSで外部画像ファイルの読込みを待つ

【参考】gihyo.jp記事: HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う

【参考】nakajmgtech.blogspot.jp記事: CreateJS勉強会 (第2回)に参加してきた

【参考】yoheim.net記事: [CreateJS] Bitmapクラスを使って、画像を自由自在に描画する


● 有志の方々のおかげで、CreateJS 日本語リファレンスが出来ています。英語の読めない私には大変有りがたいことです。(2015/02現在 easeljs-0.8用では無いがいずれ更新されるでしょう)

CreateJS日本語リファレンス:CreateJS 日本語リファレンス

 

以上です。


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]