POPSブログ

CreateJS Loading Shape (弧状) 回転テスト3

267

  Category:  javascript2013/12/22 pops 

画像読み込み時に表示するLoading、扇形をarc()で弧状に円周に配置し、イベント毎に単純にShapeをrotationで回転させています。グラフイックを書き換えて回転する形式では有りません。(グラフイック書き換え方式も掲載)
easeljs-0.7 でのテストです。

 

CreateJS Loading Shape (弧状) 回転テスト3


前回まではtransformPoint()を利用していましたが、今回は、matrix変換、transformPoint()を利用していません、単純に rotation で回しているだけです。


尚、従来のイベント毎にグラフイックを書き換えて回転する形式も最後に掲載しておきます。

[イベント毎にグラフイックを書き換えて回転する形式]


DEMO-1


CreateJS Loading Shape (弧状) 回転テスト3 デモ1、(createJS052.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

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


//日本語
//createJS052.js
//Loadingデモ3
//easeljs-0.7用

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

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

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

//split分割数 1-12
var split=12;
//弧の半径
var radius=15;
//回転の角度右正転5-30
var angle=15;//DEG
//正転逆転フラグ 右正転=1 左逆転=-1
var rotateflag=-1;
//更新角度係数 0.25-1
var angle_no=1;
//透明度をライン毎に変更 true false
var alphaChg=true;
//ライン幅
var lineWidth=3;
//ライン補正ラインの角度を広げる1-1.02
var lineScale=1;
//始点の角度
stAngle=-Math.PI/2;

//回転正逆補正
angle *=rotateflag;

//テキスト使用
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();

	//loading容器
	loadingShape=new createjs.Shape();
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/2;
	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!");

	//描画
	set_loading();

	//Listener
	createjs.Ticker.setFPS(20);
	createjs.Ticker.addEventListener("tick",loading_rotate);

}

//回転グラフイック
function set_loading() {

	var count=split;//分割
	var start_angle=stAngle;//始点の角度
	var end_angle=0;//終点の角度

	//透明度
	var alpha_v=1;

	//16進カラーをrgbの形式に変換、面倒
	var rgbArr=toRgb(loadingbackcolor);

	//graphicのスタイル
	var graphics=new createjs.Graphics();
	graphics.setStrokeStyle(lineWidth,"butt");//butt round square

	//弧の角度
	var angle_w=Math.PI*2/count;

	//ライン描画
	for (var i=0; i < count; i++){

		//透明度をライン毎に変更
		if (alphaChg && count > 0) {
			alpha_v -=0.05;
		}

		//描画角度、lineScaleは補正値
		//左回転用
		if (rotateflag != 1) {
			start_angle +=angle_w*angle_no;
			end_angle=start_angle+(angle_w*angle_no*lineScale);
		}
		//右回転用
		if (rotateflag == 1) {
			start_angle -=angle_w*angle_no;
			end_angle=start_angle+(angle_w*angle_no*lineScale);
		}

		//虹色計算alpha無し
		//var alphaback=createjs.Graphics.getHSL(i/count*360,100,50);

		//var alphaback=createjs.Graphics.getRGB(255,0,0,alpha_v);
		//rgbaのデータ設定alpha
		var alphaback=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2],alpha_v);

		//rgbaのデータ設定を適用.moveTo(0,0).closePath()
		graphics.beginStroke(alphaback).arc(0,0,radius,start_angle,end_angle);

	}
	loadingShape.graphics=graphics;
	stage.update();

}

//Ticker
function loading_rotate(event) {
	loadingShape.rotation +=angle;
	stage.update();
}

//変換は配列で返すナントカ使える
function toRgb(bc) {
	bc=bc.replace("#","");
	var rgbArr=[];
	rgbArr[0]=parseInt(bc.slice(0,2),16);
	rgbArr[1]=parseInt(bc.slice(2,4),16);
	rgbArr[2]=parseInt(bc.slice(4,6),16);
	return rgbArr;
}

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

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

init();

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


CSS

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


/*日本語 createJS052.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;
}

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


簡単な説明


Loadingをイベント毎に回転、(グラフイックを書き換え無い形式)


[説明図]

 

1つのShape内の半径 radius の円周上、に扇形を描画しているだけです。
(図は、-Math.PI/2 で補正されて、描画開始位置を左に90度回転した状態です)


設定変更で色々と変化を付ける

何時も同じでは詰まりませんので、設定変更で色々と変化を付けられる様にして見ました。

1. 大きさなどを変える。(描画数も変更可能)
2. 回転を逆にする。回転速度を変える。
3. 透明度を与える。(注意、透明度が低い場合、マシン環境が悪いと表現出来ない、要素の色、背景色によっても見た目が違ってくるので確認が必要、透明度1-0.4位の範囲にするのが無難)
4. 色の変更。
5. Operaの場合に arc()、arcTo()の描画が少し違います。これはキャンバス基準の解釈違いに起因するものと思います。角丸も正確に成らずこわれますから...
(ライン幅が狭い場合は全て同じで、Operaの不具合は見えません)

図の様に設定変更で、色々と変化できますので、1つ原型を作れば利用価値が有ります。


大きさなどを変える

大きさなどを変更出来ます。radius 円周上配置位置の半径です。
ラインの描画で、setStrokeStyle()、beginStroke()の設定で描写しています。


下記の様に設定を変更出来ます。ブラウザ及び、半径、線の太さなどにより見え方に差異があります。


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

//split分割数 1-12
var split=12;
//弧の半径
var radius=15;
//回転の角度右正転5-30
var angle=15;//DEG
//正転逆転フラグ 右正転=1 左逆転=-1
var rotateflag=-1;
//更新角度係数 0.25-1
var angle_no=1;
//透明度をライン毎に変更 true false
var alphaChg=true;
//ライン幅
var lineWidth=3;
//ライン補正ラインの角度を広げる1-1.02
var lineScale=1;

//始点の角度
stAngle=-Math.PI/2;

1. 回転の角度、回転速度になりますが、デグリー値です。
2. 正転逆転フラグ、右正転=1 左逆転=-1の値です。
正逆の切り替えで、透明度なども自動で反転しますから、他の設定変更は要りません。
3. 更新角度係数、円周配置の割合です。0.9、0.8 等は隙間が出来ます。0.5では半周配置。
(描画数 1 の場合「円」を描画しますので、隙間が無いと回転は見えません)
4. 透明度をライン毎に変更、段階的に透明度を変えます。alpha_v -=0.05 の設定です。
5. ライン補正、余り必要では無いが各ラインの隙間を少し補正できます。
(逆に1より値が小さいと破線になります)
6. 始点の角度、Math.PI計算では原点は3時方向です。12時方向に修正しています。
(回転するので修正無しでも何ら問題は無い)


段階的に透明度を変える

段階的に透明度を変えています。alpha_v -=0.05 の値になっていますが、分割が多いと最後の方が消える場合がありますので調整下さい。
尚、要素の色、背景色、ブラウザ、モニター、マシン環境により表現に差があり見た目が違う。



//透明度をライン毎に変更
if (alphaChg && count > 0) {
	alpha_v -=0.05;
}

透明度を与える

透明度を与えるには rgba 形式で色情報及び透明度を指定します。(黒色、透明度無し)

段階的に透明度を与えていますので、ループの中で変更します。(一律の場合はループ外で設定可能)


graphics.beginStroke("rgba(0,0,0,1)")....

CreateJSでは、getRGB()で r g b alpha を指定します。(赤色、透明度50%)


createjs.Graphics.getRGB(255,0,0,0.5)

記載例
graphics.beginStroke(createjs.Graphics.getRGB(255,0,0,0.5)).arc....;

色変更の場合に、RGB形式で記載するのは結構面倒です...


● 16進カラーをRGB値に変換

getRGB(255,0,0,0.5)等と記載は面倒なので、16進カラーをRGB値に変換して利用しています。
16進カラーは "#000000" の形式で使用の事。透明度は別途計算して記載下さい。


//16進カラーをrgbの形式に変換
var rgbArr=toRgb(loadingbackcolor);
var rgbArr=toRgb("#FF0000");

RGB値が下記配列で取得できる、透明度は別途計算する
rgbArr[0] rgbArr[1] rgbArr[2]

createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2],透明度);
で使用できる

● 透明度を変えない場合


graphics.beginStroke("#FFFFFF")....

rgba形式でないなら、透明度は変化しない。


虹色に染める

以下の様に書き換えると、虹色に染まりますが透明度の変化は有りません。


以下を有効にする

//虹色計算alpha無し
var alphaback=createjs.Graphics.getHSL(i/count*360,100,50);

以下を無効にする

//rgbaのデータ設定alpha
//var alphaback=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2],alpha_v);

インスタンスの回転

一般的な rotation 回転です。


//Ticker
function loading_rotate(event) {
	loadingShape.rotation +=angle;
	stage.update();
}

最終段の「デモ2」はグラフイックを書き換えて回転する形式です。


描画角度の計算

arc()の描画では、「開始点の角度」「終点の角度」が必要ですが、「次ぎの開始点角度」は「前の終点角度」と成る計算をしています。
正逆転、隙間補正などの計算のために少し繁雑です。終点角度end_angleを広げたりしているだけですが。


//描画角度、lineScaleは補正値
//左回転用
if (rotateflag != 1) {
	start_angle +=angle_w*angle_no;
	end_angle=start_angle+(angle_w*angle_no*lineScale);
}
//右回転用
if (rotateflag == 1) {
	start_angle -=angle_w*angle_no;
	end_angle=start_angle+(angle_w*angle_no*lineScale);
}

Operaの場合に arc()の描画が少し違います

修正を試みましたが直りません。他のブラウザでは正常ですから、これは、HTML5基準キャンバス仕様の解釈の違いに起因するものと思います。arcTo()に至っては描画図形が逆転しますから問題です。
将来、これらの問題が解決されるかはわかりません。弧、扇形の描画は面倒過ぎますので正常に描かれた人のものをパクッタほうが利口と思います。面倒で時間の浪費が甚だしい。


実際の組み込み

「デモ」では表示回転させているだけですので、実際に組み込む場合は其れなりに工夫ください。マシン環境が悪い場合に、負荷が大きいと回転は落ちます。




 

 

イベント毎にグラフイックを書き換えて回転する形式

結構悩んだがデキタ!


円周配置位置にarcで扇形をイベント毎にグラフイックを書き換え描画して行く方式、ずらすにはmatrix変換、transformPoint()を利用しますが、移動位置の角度を計算して再描画します。面倒なだけで効率が良い訳では有りません。一応「デモ2」として掲載しておきます。
Loading以外で役に立つ事が在るかも知れません。!?


DEMO-2. JS. 簡単な説明


CreateJS Loading Shape (弧状) 回転テスト3b デモ2、(createJS052b.js)


JS

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


//日本語
//createJS052b.js
//Loadingデモ3b
//描画角度を移動角度に合わせる
//easeljs-0.7用

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

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

//split分割数 1-12
var split=12;
//弧の半径
var radius=25;
//回転の角度右正転5-30
var angle=15;//DEG
//正転逆転フラグ 右正転=1 左逆転=-1
var rotateflag=1;
//更新角度係数 0.25-1
var angle_no=1;
//透明度をライン毎に変更 true false
var alphaChg=true;
//ライン幅
var lineWidth=3;
//ライン補正ラインの角度を広げる1-1.02
var lineScale=1;
//始点の角度
stAngle=-Math.PI/2;

//回転正逆補正
angle *=rotateflag;

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

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

var stage;
var viewtext;

var loadingShape;
var matrix1=new createjs.Matrix2D();
var loadingpoints1=[];

//shadowフィルター
var shadow=new createjs.Shadow("#FFFFFF",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.Shape();
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/2;
	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!");

	//位置の決定
	initPoints();
	//描画
	draw_loading();

	//Listener                                                                                                     
	createjs.Ticker.setFPS(20);
	createjs.Ticker.addEventListener("tick",loading_rotate);

}

//Ticker
function loading_rotate(event) {

	//matrix変換
	var count=loadingpoints1.length;
	matrix1.identity().rotate(angle*createjs.Matrix2D.DEG_TO_RAD);
	//point決定
	for (var i=0; i < count; i++) {
		var point=loadingpoints1[i];
		matrix1.transformPoint(point.x,point.y,point);
	}

	//書換え
	draw_loading();
}

//初期描画位置計算
function initPoints() {

	var count=split;
	var alpha_v=1;
	var radius_v=radius;//サークル半径

	//描画データ
	var cx,cy,
	cAngle=stAngle,//始点の角度
	nAngle;

	//描画位置計算/設定変更値で位置決め
	nAngle=Math.PI*2/count*angle_no;
	for (var i=0; i < count; i++){

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

		//外周位置計算、更新角度係数補正
		cx=Math.cos(cAngle)*radius;
		cy=Math.sin(cAngle)*radius;
		//位置保存
		loadingpoints1.push(new createjs.Point(cx,cy));

	}

}

//回転グラフイック書換え
function draw_loading() {

	var count=loadingpoints1.length;//保存数で計算
	var start_angle=stAngle;//始点の角度
	var end_angle=0;//終点の角度

	//透明度
	var alpha_v=1;

	//16進カラーをrgbの形式に変換、面倒
	var rgbArr=toRgb(loadingbackcolor);

	//graphicのスタイル
	var graphics=new createjs.Graphics();
	graphics.setStrokeStyle(lineWidth,"butt");//butt round square
	loadingShape.graphics.clear();

	//弧の角度
	var angle_w=Math.PI*2/count*angle_no;

	//ライン描画
	for (var i=0; i < count; i++){

		//原点移動はしない移動角度を修正する
		//pointでstart_angleを決定
		var _point=loadingpoints1[i];
		start_angle=Math.atan2(_point.y,_point.x);

		//透明度をライン毎に変更
		if (alphaChg && count > 0) {
			alpha_v -=0.05;
		}

		//描画角度を移動角度に合わせる、lineScaleは補正値
		//左回転用
		if (rotateflag != 1) {
			//start_angleはそのまま
			end_angle=start_angle+(angle_w*lineScale);
		}
		//右回転用
		if (rotateflag == 1) {
			start_angle -=angle_w;
			end_angle=start_angle+(angle_w*lineScale);
		}

		//虹色計算alpha無し
		//var alphaback=createjs.Graphics.getHSL(i/count*360,100,50);

		//var alphaback=createjs.Graphics.getRGB(255,0,0,alpha_v);
		//rgbaのデータ設定alpha
		var alphaback=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2],alpha_v);

		//rgbaのデータ設定を適用
		graphics.beginStroke(alphaback).arc(0,0,radius,start_angle,end_angle);

		loadingShape.graphics=graphics;

	}
	stage.update();
}

//変換は配列で返すナントカ使える
function toRgb(bc) {
	bc=bc.replace("#","");
	var rgbArr=[];
	rgbArr[0]=parseInt(bc.slice(0,2),16);
	rgbArr[1]=parseInt(bc.slice(2,4),16);
	rgbArr[2]=parseInt(bc.slice(4,6),16);
	return rgbArr;
}

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

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

init();

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


イベント毎の角度の補正

arc扇形の円周配置位置を保存しておき、matrix変換、transformPoint()を利用して、ポイントを移動しますので移動ポイントの角度を計算して、描画角度を修正しています
transformPoint()は位置の変更用です。配置要素の位置は0で常に変わりませんので、円周に仮のポイントを作りその角度を利用して見ました。角度の補正は、描画角度を決める前に修正すれば良いのだが結構悩んだ...。

この手法は他に役に立つかも知れない...


回転速度の関係で見た目「分割が余計」に見えるのは目の錯覚です。描画処理の遅い場合も違って見えます。回転速度が拠り大きいと逆転して見えたリします。


 

従来(前、前々ページのJS)の方法でポイントを移動をさせると、描画がメチャに成る場合がある。この辺「arc仕様」は難しい。色々な方法は有ると思うが.........


従来の手法は、だめだ
graphics.moveTo(_point.x,_point.y);

● ここでの、arc扇形は位置では操作できないから、下記の様にしなければならないようだ。一番簡素のような気がする
保存してある外周位置より角度を求め、arc扇形描写の開始角度 start_angle にします。つまり目的の位置にグラフイックを描画する事になる。
最初のグラフイックを書き換えないJSをベースに変更しています。



//回転グラフイック書換え
function draw_loading() {

	var count=loadingpoints1.length;//保存数で計算
	var start_angle=stAngle;//始点の角度
	var end_angle=0;//終点の角度

	//透明度
	var alpha_v=1;

	//16進カラーをrgbの形式に変換、面倒
	var rgbArr=toRgb(loadingbackcolor);

	//graphicのスタイル
	var graphics=new createjs.Graphics();
	graphics.setStrokeStyle(lineWidth,"butt");//butt round square
	loadingShape.graphics.clear();

	//弧の角度
	var angle_w=Math.PI*2/count*angle_no;

	//ライン描画
	for (var i=0; i < count; i++){

		//原点移動はしない移動角度を修正する
		//pointでstart_angleを決定
		var _point=loadingpoints1[i];
		start_angle=Math.atan2(_point.y,_point.x);

		//透明度をライン毎に変更
		if (alphaChg && count > 0) {
			alpha_v -=0.05;
		}

		//描画角度を移動角度に合わせる、lineScaleは補正値
		//左回転用
		if (rotateflag != 1) {
			//start_angleはそのまま
			end_angle=start_angle+(angle_w*lineScale);
		}
		//右回転用
		if (rotateflag == 1) {
			start_angle -=angle_w;
			end_angle=start_angle+(angle_w*lineScale);
		}

		//虹色計算alpha無し
		//var alphaback=createjs.Graphics.getHSL(i/count*360,100,50);

		//var alphaback=createjs.Graphics.getRGB(255,0,0,alpha_v);
		//rgbaのデータ設定alpha
		var alphaback=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2],alpha_v);

		//rgbaのデータ設定を適用
		graphics.beginStroke(alphaback).arc(0,0,radius,start_angle,end_angle);

		loadingShape.graphics=graphics;

	}
	stage.update();
}

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

任意の位置から原点との角度を得る
Math.atan2(Y位置,X位置);

追随するインスタンス

仮に、グラフイックのインスタンスを作り、pointの位置に合わせれば、先頭に追随することになる。
但し、回転しないので、サークル位しか描けない。(matrixで回転は可能と思います)


if (i == 0) {
	図形インスタンス.x=_point.x+canvasWidth/2;
	図形インスタンス.y=_point.y+canvasHeight/2;
}

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

追随するインスタンスの例、インスタンスを準備

var loadingShape2;

ローデングloadingShapeの上に配置

loadingShape2=new createjs.Shape();
loadingShape2.graphics.beginFill("#FFFFFF").drawCircle(0,0,2);
stage.addChild(loadingShape2);

位置情報取得、start_angle=Math.atan2(_point.y,_point.x);の直下あたりで
以下を記載すれば、ついてくる

if (i == 0) {
	loadingShape2.x=_point.x+canvasWidth/2;
	loadingShape2.y=_point.y+canvasHeight/2;
}

ローデングloadingShapeの中に描く事も可能で在ろうが試したことは無い。


設定方法などは同じ

初期設定方法、虹色、透明度変更などの方法は、上記のcreateJS052.jsと同じになります。
CSSなども共通です。


比較して軽くなったような気がしないので、「グラフイックを書き換え描画」が良いのかは判断できない。



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


arc扇形は疲れる....、以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]