POPSブログ

CreateJS Loading 円周上にShapeを配置し、コンテナを回転させる簡易形です

268

  Category:  javascript2014/01/01 pops 

画像読み込み時に表示するLoading、コンテナの円周上に図形Shapeを配置し、イベント毎に回転する形式ですが親であるコンテナを回転させて、グラフイックの書き換えを行っていない簡単なものです。
円周配置の図形Shapeの角度を変更出来ますので多用な形に作れます。
easeljs-0.7 でのテストです。

 

CreateJS Loading Shape コンテナ回転簡易形、テスト4


図形Shapeを配置した親であるコンテナを回転させれば、簡単です。前のものは、matrix変換、transformPoint()を利用してrotation させて要る特殊なものでした。
「Loading」として使用するならば、簡単な作りのほうが便利と思いますが、...


 

 

DEMO


CreateJS Loading Shape コンテナ回転簡易形、テスト4、(createJS053.js)

このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。
/// 注意、ブラウザ、マシン性能により描画品質などに大きな差が有ります事了承下さい ///


Chrome Firefox Safari(Win) IE9、で動作確認済み。 Safari(Mac)、IE10、は未確認です。


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

ダウンロードしたJSを使用する場合。記述は一例です。(バージョン 0.7.0 使用)


<script type="text/javascript" src="js/easeljs-0.7.0.min.js"></script>

重要、バージョン違いでは動かない場合が有りますので必ず合わせて下さい。
このデモでは、preloadjs tweenjs は必要では有りません。


HTML (HTML5)


<div id="demo-wrap">
	<div id="image-box">
		<canvas id="mainCanvas" width="640" height="300"></canvas>
	</div>
</div>

JS

createJS053.js、JS名は任意に変更可。注意、easeljs-0.7用です。


//日本語
//createJS053.js
//Loadingデモ4 簡易楕円
//easeljs-0.7用

//--------------------------------------------------------------

//canvasの大きさ/全てこの値を使用
var canvasWidth=640;
var canvasHeight=300;

//回転速度 デグリー値5-20
var angle=10;//DEG

//テキスト使用
var textUse=true;

//--------------------------------------------------------------

var stage;
var viewtext;
var loadingShape;

//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);

function init() {

	stage=new createjs.Stage("mainCanvas");

	//バックRect/最下位色背景層、無くとも良い
	var backrect=new createjs.Shape();
	backrect.graphics.beginFill("#000000").drawRect(0,0,canvasWidth,canvasHeight);
	stage.addChild(backrect);
	stage.update();

	//空コンテナインスタンス配置
	loadingShape=new createjs.Container();
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/2;
	//Loading描画
	make_loading();
	//tickListenerを設定
	createjs.Ticker.setFPS(20);
	loadingShape.tick=function (){
		loadingShape.rotation +=angle;
		//こちらでupdate
		stage.update();
	};
	//loading addEventListenerを設定
	createjs.Ticker.addEventListener('tick',loadingShape.tick);
	stage.addChild(loadingShape);


	//簡易TEXT
	viewtext=new createjs.Text("","12px Arial","#FFFFFF");
	viewtext.x=20;
	viewtext.y=15;
	viewtext.maxWidth=canvasWidth-40;
	viewtext.lineHeight=20;
	viewtext.textBaseline="bottom";
	viewtext.shadow=shadow;//SHADOW処理
	stage.addChild(viewtext);

	//TEXT
	set_text("Loading Now!");

	//未使用
	//createjs.Ticker.addEventListener('tick',tick);

}

//Main-Ticker 未使用
function tick() {
	stage.update();
}

//描画
function make_loading() {

	//Loadingの色
	var loadingbackcolor="#FF1493";
	var loadingbackcolor2="#FFFFFF";//2色用

	//split分割数 3-12
	var split=12;
	//半径
	var radius=25;
	//正転逆転フラグ 右正転=1 左逆転=-1
	var rotateflag=1;
	//パーツ補正角度
	var partsAngle=0;
	//透明度を描写毎に変更 true false
	var alphaChg=true;
	//虹色にする 優先不透明 true false
	var rainbowColor=false;
	//2色に染める不透明 虹色優先 false true
	var color2Use=false;


	//回転正逆補正
	angle *=rotateflag;
	if (rainbowColor) {color2Use=false;}//虹色優先

	//半径 PolyStar
	var parts_radius=5;
	//パーツの大きさ Ellipse 5x10,Rect Leaf 10x10
	var parts_w=5;
	var parts_h=10;

	//描画データ
	var count=split;
	var cAngle=-Math.PI/2;//始点の角度
	var nAngle;
	nAngle=Math.PI*2/count;

	//初期透明度
	var alpha_v=1;

	var chipflag=1;
	var alphaback=loadingbackcolor;
	var cx,cy;
	var kk=1;

	for (var i=0; i < count; i++){

		//回転補正
		if (rotateflag != 1) {cAngle +=nAngle;chipflag=1;}
		if (rotateflag == 1) {cAngle -=nAngle;chipflag=-1;}

		cx=Math.cos(cAngle)*radius;
		cy=Math.sin(cAngle)*radius;

		//透明度を描画毎に変更
		if (alphaChg && i > 0) {
			alpha_v -=0.05;
		}
		//不透明虹色
		if (rainbowColor) {
			alphaback=createjs.Graphics.getHSL(i/count*360,100,50);//直接
			alpha_v=1;
		}
		//不透明2色
		if (color2Use) {
			alphaback=loadingbackcolor;
			if (kk < 0) {alphaback=loadingbackcolor2;}
			alpha_v=1;
		}

		//図形用インスタンス配置
		var s=new createjs.Shape();
		s.x=cx;
		s.y=cy;
		s.alpha=alpha_v;//透明度alphaで処理
		s.id=i;

		//逆転しても同じに修正する
		var angle_r=(chipflag*360/count*(i+1))-partsAngle*rotateflag;
		s.rotation=angle_r;

		//回転グラフイック書換え

		//Ellipse
		s.graphics.beginFill(alphaback).drawEllipse(-parts_w/2,-parts_h/2,parts_w,parts_h);

		//PolyStar
		//s.graphics.beginFill(alphaback).drawPolyStar(0,0,parts_radius,5,parts_radius/2,0);

		//Rect
		//s.graphics.beginFill(alphaback).drawRect(-parts_w/2,-parts_h/2,parts_w,parts_h);

		//Leaf
		//s.graphics.beginFill(alphaback);tileLeaf(s,parts_w/2,parts_h/2,1);//1 -1

		loadingShape.addChild(s);

		kk *=-1;
	}

}

//Leaf
function tileLeaf(s,w,h,k) {
	var rate=1;//0.8 1.4
	s.graphics.moveTo(-w,-h*k)
	.quadraticCurveTo(w*rate,-h*rate*k,w,h*k)
	.quadraticCurveTo(-w*rate,h*rate*k,-w,-h*k);
}

//VIEWTEXT
function set_text(t) {
	if (textUse) {
		viewtext.text=t;
		stage.update();
	}
}

//--------------------------------------------------------------

init();

注釈文を削除すれば、幾分早くなります。
画像使用の場合、登録画像パスは当方の例です。使用の際は環境に合わせて下さい。


CSS

createJS053.css、CSS名は任意に変更可


/*日本語 createJS053.css*/

#demo-wrap {
text-align:center;
}

#image-box {
position:relative;
top:0;left:0;
width:640px;
height:300px;
margin:0 auto;
padding:0;
border:1px #CCCCCC solid;
background-color:#FFFFFF;
}

当方のサンプルの例です。


簡単な説明


[説明図]

 

外周に配置した図形の配置角度を変更できるように、Shape()インスタンスを作り外周に並べています。直接graphicsで配置した場合には角度をを変えられないものも有るからです。
その為に複数のShape()インスタンスをコンテナに収容して、コンテナを回転する仕組みです。


1. 大きさ、図形の配置角度、回転速度など変更可能です。
2. 図形の形は、該当部分を書き換えてください。使用しない関数は削除できます。
3. PolyStarの場合、中の設定値(引数)でも、角度の変更可能です。
4. 透明度を段階的に変える事が可能です。但し1色の場合のみ。
5. Loadingに星形など必要か大変疑問に思う今日この頃です。
6. テキストで「Loading中」を表示するなら「Loading」は要らない。(超簡単!最近気づいた)
7. 回転させる目的ならば「Loading」以外での使用も出来ます。


大きさなどを変える

大きさなどを変更出来ます。radius 円周上配置位置の半径です。
図形の描画は、beginFill()の設定で行っています。


下記の様に設定を変更出来ます。ブラウザ及び、大きさ、透明度などにより見え方に差異があります。


全体の半径、分割、速度などの設定


//Loadingの色 かならず#xxxxxxの16進カラー形式で記入のこと
var loadingbackcolor="#FF1493";
var loadingbackcolor2="#FFFFFF";//2色用

//split分割数 3-12
var split=12;
//半径
var radius=10;
//正転逆転フラグ 右正転=1 左逆転=-1
var rotateflag=-1;
//パーツ補正角度
var partsAngle=0;
//透明度を描写毎に変更 true false
var alphaChg=true;
//虹色にする 優先不透明 true false
var rainbowColor=false;
//2色に染める不透明 虹色優先 false true
var color2Use=true;

円周配置の図形の大きさ


//半径 PolyStar
var parts_radius=5;
//パーツの大きさ Ellipse 5x10,Rect Leaf 10x10
var parts_w=5;
var parts_h=10;

実際の組み込み

コンテナloadingShapeにEventListenerを設定して、回転させているだけです。loadingShape設定直下に書くか、分離するかの違いです。以下回転動作は同等です。
● 使用する場合に、コンテナloadingShapeを「表示」して、EventListenerを設定する。
● 使用しない場合は、コンテナloadingShapeを「非表示」にして、EventListenerを削除する。


● 回転速度

回転速度は rotation で動かしているので、デグリー値を使用します。逆転する場合にマイナス値は不要です。
正転逆転フラグの値で逆転できます。


var angle=10;

//正転逆転フラグ 右正転=1 左逆転=-1
var rotateflag=1;

EventListenerの設定

Loadingは常時使用するものではなく、必要な場合に表示するのが一般的と思います。
EventListenerも「Loading」を使用しない時は「削除」するのが理想的です。


● EventListenerの設定、削除の書式は以下の様になるが、
リスナーである「関数またはオブジェクト」を指定しないと削除できない不便さがある。
尚、.removeAllEventListeners()を使う手もあるが、大まかな削除に成る。


オブジェクト.addEventListener(type,listener)
オブジェクト.removeEventListener(type,listener)

Loading操作の扱いやすい EventListener はどう記述するかが問題である。


● EventListenerを分離して書く
問題の出難い、一番安心出来る書き方です。(このデモでは違う方法で設定している)


//空コンテナインスタンス配置
loadingShape=new createjs.Container();
loadingShape.x=canvasWidth/2;
loadingShape.y=canvasHeight/2;
//Loading描画
make_loading();
stage.addChild(loadingShape);

//EventListenerを設定
loadingShape.addEventListener('tick',loading_tick);

---------------------------------------------------------------
//Listener
function loading_tick() {
	loadingShape.rotation +=angle;
	//出来ればupdateは他で実行したい
	stage.update();
}

---------------------------------------------------------------
//EventListenerを削除
loadingShape.removeEventListener('tick',loading_tick);

その他の設定方法もあるが、マチガイがおき易くまたリスナーの削除が困難になる。


● その他のEventListener設定の書き方

次ぎの tickイベント、EventListener設定は stage.update() を書き込むと機能しません。エラーに成りますので注意下さい。stage.update()無しなら正常に機能します。

尚、イベントの種類が tick 以外ならば update() は機能する。マチガイの元になるので使用を避けた方が無難かも!
またEventListenerを削除するのが困難であるし、再設定も面倒になる。


//空コンテナインスタンス配置
loadingShape=new createjs.Container();
loadingShape.x=canvasWidth/2;
loadingShape.y=canvasHeight/2;
//Loading描画
make_loading();
stage.addChild(loadingShape);

//EventListener
loadingShape.addEventListener('tick',function (){
	//この部分はOK
	loadingShape.rotation +=angle;
	//updateはエラーです
	stage.update();
});

この書き方は一般に「mouseover」などの「マウスイベント」の書き方に多用されている様です。
「マウスイベント」の場合はボタンなどにEventListenerを設定したら、その後のEventListener削除は余り無い。


判定子で制御できるが、常時EventListenerを作動させておくので負荷が掛かる。


var 判定子=true;

//EventListener
loadingShape.addEventListener('tick',function (){
	if (判定子) {
		loadingShape.rotation +=angle;
	}
}

.addEventListener('tick',function (){})、が将来改良なればウレシイ所である。


どうしても上記の方法を使用するならば、updateのみ他のTickerで実行させればエラーにならず機能する。


//EventListener
loadingShape.addEventListener('tick',function (){
	//updateは他で実行する
	loadingShape.rotation +=angle;
});

//update専用EventListener
createjs.Ticker.addEventListener('tick',tick);

---------------------------------------------------------------
//update専用
function tick() {
	stage.update();
}

● 上記の書き方でEventListenerを削除出来る様にするならば、以下の様に書けるが update はエラーに成る
easeljs-0.7よりEvent.currentTargetでインスタンスを参照出来ますから、別の書き方も出来る。但しほとんどはマウスイベントに用いられているが、


loadingShape.addEventListener('tick',loadingShape_tick);

---------------------------------------------------------------

//loadingShape用
function loadingShape_tick() {
	loadingShape.rotation +=angle;
	//updateはエラーです
	//stage.update();
}

//EVENTよりインスタンス判定
function loadingShape_tick(eventObject) {
	eventObject.currentTarget.rotation +=angle;

}
---------------------------------------------------------------
//EventListener削除
loadingShape.removeEventListener('tick',loadingShape_tick);

多々設定方法はあるようですが、状況に応じて工夫が必要のようです。


「デモ」のEventListenerの設定

「デモ」では、EventListener設定削除が容易なため、以下の方法で設定しています。


次ぎのEventListener設定方法でも「可能の様」です。(正常に機能しますが、使用方法が正しいかは別問題です)
インスタンス直下で設定出来るのが便利なんですが...
ここで、stage.update()も行なうと、少しの負荷で回転が遅くなるので、
stage.update()は他で行なったほうが良いかも知れない。(update専用のTickerなど...)


● loadingShape.tick=function で回転さす
TickerはaddListenerしたオブジェクトに対して、定期的にコールする仕組みを持っています。
「デモ」ではこちら使用しています。以下動作はするが、使用例は少ない。


loadingShape.tick=function (){
	loadingShape.rotation +=angle;
	stage.update();
};
//loading addEventListenerを設定
createjs.Ticker.addEventListener('tick',loadingShape.tick);

---------------------------------------------------------------
//EventListenerを削除
createjs.Ticker.removeEventListener('tick',loadingShape.tick);

これなら、EventListenerの設定、削除が簡単にできる。(loadingShapeの設定直下に書けるのが便利)


次のように分離しても良い(面倒だから使用はしていない)。


loadingShape.tick=function (){
	loadingShape.rotation +=angle;
};
//loading addEventListenerを設定
createjs.Ticker.addEventListener('tick',loadingShape_tick);

---------------------------------------------------------------
//loadingShapeTicker
function loadingShape_tick() {
	loadingShape.tick();
	stage.update();
}

---------------------------------------------------------------
//EventListenerを削除
createjs.Ticker.removeEventListener('tick',loadingShape_tick);

以下でもよいが、EventListenerを削除するのが困難


loadingShape.tick=function (){
	loadingShape.rotation +=angle;
};
stage.addChild(loadingShape);

//EventListener
createjs.Ticker.addEventListener('tick',function() {
	loadingShape.tick();
	stage.update();
});

全て、作動するが、どれが正しいのだろうか?


stage.update()は専用のTickerで実行する

上記、stage.update()を、各EventListener設定の中で行っていますが、stage.update()専用の関数で行なったほうが動作がスムーズのようです。(マシン性能が良ければ問題ない)
現実的にワタシの場合、どうしても、個別に EventListener 設定して、stage.update()を行なうことが多くなります。


stage.update()実行については、下記の様に1本化するように推奨されていますが、常時stage.update()が行なわれては困る時も有るし、負荷の面から考慮すると中々出来ない時もある。この辺は臨機応変に処理するしかない!。


createjs.Ticker.addEventListener('tick',tick);

---------------------------------------------------------------
//update専用
function tick() {
	stage.update();
}

透明度変化の調整

段階的に透明度変化させる度合いの値ですが、透明度が低いと「性能の悪い環境」では見えませんので、100%-30%位の間で使用するようにしています。透明度は図形インスタンスをalphaで調整しています。
分割数、または色、背景色などの状況により、値を変えます。
下記例では 20分割 で最後の透明度が 0 に成る。実際にはその前にほぼ見えなくなるので調整する。


//透明度を描画毎に変更
if (alphaChg && i > 0) {
	alpha_v -=0.05;
}

外周配置図形

標準では楕円にしている。大きさ設定は幅高さを使用しているが、PolyStarは半径を使用している。
縦横の寸法を反対に設定すれば、90度違った配置になる。
PolyStarの回転の修正は最後の引数でも出来る。(初期値は 0 にしている)
円形の場合は、楕円(Ellipse)の縦横同じ寸法にすれば円に成る。


//半径 PolyStar
var parts_radius=5;
//パーツの大きさ Ellipse 5x10,Rect Leaf 10x10
var parts_w=5;
var parts_h=10;

//Ellipse
s.graphics.beginFill(alphaback).drawEllipse(-parts_w/2,-parts_h/2,parts_w,parts_h);

必要に応じて図形を選定すれば良い、PolyStarは5角形になっているがこの辺は自由です。
Leafは 10x10 の様に縦横同じにする、違う場合は変形した形になるがこれも面白い。


//PolyStar
//s.graphics.beginFill(alphaback).drawPolyStar(0,0,parts_radius,5,parts_radius/2,0);

//Rect
//s.graphics.beginFill(alphaback).drawRect(-parts_w/2,-parts_h/2,parts_w,parts_h);

//Leaf
//s.graphics.beginFill(alphaback);tileLeaf(s,parts_w/2,parts_h/2,1);//1 -1

円形をdrawCircleで描画するには次ぎの様になる。円形のためパーツ補正角度は反映されない。


//Circle
s.graphics.beginFill(alphaback).drawCircle(0,0,parts_radius);

ラインを描画する場合は下記の様になる。両端はround。


//Line
s.graphics.setStrokeStyle(parts_w,"round");//butt round
s.graphics.moveTo(0,-parts_h/2);
s.graphics.beginStroke(alphaback).lineTo(0,parts_h/2);

回転速度

回転速度によって、見栄えが違いますので、確認しながらあわせます。
1色で、透明度を与えない場合は、分割によっても違うが回転させても変化の無い角度も有ります。(12分割は30度で図形が配置される、30度の速度では同じ位置になり回転は止まって見える)
よって、透明度の変化、色違いなど与えた方がいかなる回転角度(速度)にも対応出来ることに成る。


その都度、EventListenerを設定、削除

Loadingの使用は、一括して全ての画像を読み込む場合は1回の設定で済むが、その都度画像を読み込む場合は、複数回Loadingを使用する事になる。
その為、EventListenerを削除せずに、次のようにして使用する事を考えたが、....


var loading=true;

loadingShape.tick=function (){
	if (loading) {
		loadingShape.rotation +=angle;
		stage.update();
	}
};

実際に、色々と作りこむとEventListenerが増えてくるので、キャンバスの処理能力の点からEventListenerは常に設定、削除をして負荷のかからない様にする必要性がある。結局この方法はやめた。

現在は面倒でも、EventListenerの設定、削除を実行する様にしている。(今後処理能力が向上すればこの限りでは無いし、その時々の負荷の度合いで判断しても良いかも知れない)


テキストでLoadingを表示

何と言っても、テキストで「Loading中」を表示するのが一番簡単である。面倒なことを考える必要がない!

 



一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。

CreateJSは結構「仕様」が変わりますので特に注意が必要です。


以上、loading に関する「能書き」です。(クダラン屁理屈を古来、能書きと呼ぶ)

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]