POPSブログ

CreateJS Matrixで円周上に配置した図形Shapeなどを回転

270

  Category:  javascript2014/01/10 pops 

円周上に配置した図形ShapeなどをMatrixクラスを使用して回転させます。画像などをも配置出来ますので色々な応用が可能です。Matrixですのでマウス位置に対応して、回転方向速度変化など操作出来ます。簡単な「デモ」と共に掲載します。
easeljs-0.7 でのテストです。

 

CreateJS Matrixで円周上に配置した図形Shapeなどを回転


Matrixクラスを使用していますので、リアルタイムに条件を変えて変化が可能になります、ここではマウスの動きにより左右回転、速度の切り替えを行なう簡単なものです。
回転速度の角度に応じてtick毎に外周位置を計算して、図形位置をMatrixで移動しているだけですが、全体が移動しているので回転しているように見えます。グラフイックの書き換えは行なっていません。


easeljs-0.8のMatrix変更

最新のeaseljs-0.8ではMatrixクラスが変更になり、以前のスクリプトは正常に動作しませんのでeaseljs-0.8用に修正しています。詳細は下記記事を参照ください。

【参照】当方の記事: CreateJS Matrixで円周配置の図形Shapeなどを回転(easeljs-0.8)


 

DEMO


CreateJS Matrixで円周上に配置した図形Shapeなどを回転 テスト、(createJS055.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

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


//日本語
//createJS055.js
//Matrix2Dデモ1
//easeljs-0.7用

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

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

//partsの色 かならず#xxxxxxの16進カラー形式で記入のこと
var partsbackcolor="#FFFFFF";
//split分割数 3-12
var split=12;
//半径
var radius=100;
//正転逆転フラグ 右正転=1 左=-1
var rotateflag=1;
//初期回転速度 デグリー値1-5
var angle=2;//DEG
//パーツ補正角度 傾き デグリー値
var partsAngle=0;
//虹色にする不透明 true false
var rainbowColor=true;
//マウスイベントの使用 true false
var eventUse=true;

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

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

//--------------------------------------------------------------
//回転正逆補正
angle *=rotateflag;
partsAngle *=rotateflag*createjs.Matrix2D.DEG_TO_RAD;
//to-RAD
var rotate_angle=angle*createjs.Matrix2D.DEG_TO_RAD;
var plusAngle=0;
//--------------------------------------------------------------

var stage;
var viewtext;
var partsContainer;

var matrix=new createjs.Matrix2D();
var chip=[];
var innerchip=[];
var stopNo=1;

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

function init() {

	stage=new createjs.Stage("mainCanvas");
	//MouseOver設定/必要に応じ設定
	stage.enableMouseOver(20);

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

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

	//簡易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("Matrix-rotation");


	//パーツを配置してBaseを作る
	set_baseCircle();

	//Listener
	createjs.Ticker.setFPS(40);
	createjs.Ticker.addEventListener("tick",parts_rotate);

	//マウスイベントの使用
	if (eventUse) {
		stage.addEventListener("stagemousemove",setAngle);
	}

}

//MOUSE
function setAngle(event) {
	var mouseX=event.stageX;
	angle=(mouseX-canvasWidth/2)*1/100;
}

//Ticker
function parts_rotate(event) {

	var count=split;

	//加算/停止処理
	plusAngle +=(angle*createjs.Matrix2D.DEG_TO_RAD*stopNo);

	//描画データ
	var cx,cy;
	var cAngle=startAngle;
	var nAngle=0;

	//描画位置
	nAngle=Math.PI*2/count;
	var chipflag=1;
	var parts_angle=0;

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

		//回転
		cAngle +=nAngle;

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

		//角度補正
		var angle_r=Math.PI/2+cAngle+plusAngle+partsAngle*rotateflag;
		//角度無し
		//var angle_r=0;

		//matrix
		matrix.identity();
		matrix.rotate(angle_r);
		//translate順序重要
		matrix.translate(cx,cy);
		matrix.decompose(chip[i]);

	}

	//update
	stage.update();

}

//base
function set_baseCircle() {

	var alphaback=partsbackcolor;

	//パーツの大きさ
	var parts_w=40;//20 40
	var parts_h=40;//40

	var count=split;

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

		//図形用インスタンス配置コンテナ
		chip[i]=new createjs.Container();
		chip[i].id=i;
		//内部図形
		innerchip[i]=new createjs.Shape();

		//Rect
		//graphicRect(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,alphaback,rainbowColor,count,i);
		//RoundRect
		graphicRoundRect(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,5,alphaback,rainbowColor,count,i);
		//Ellipse
		//graphicEllipse(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,alphaback,rainbowColor,count,i);

		chip[i].addChild(innerchip[i]);
		partsContainer.addChild(chip[i]);

	}

}

//Ellipse Graphics
function graphicEllipse(s,x,y,w,h,color,rainbow,len,no) {
	var c=color;
	if (rainbow) {
		c=createjs.Graphics.getHSL(no/len*360,100,50);//直接
	}
	//s.graphics.clear();
	s.graphics.beginFill(c).drawEllipse(x,y,w,h);
}
//Rect Graphics
function graphicRect(s,x,y,w,h,color,rainbow,len,no) {
	var c=color;
	if (rainbow) {
		c=createjs.Graphics.getHSL(no/len*360,100,50);//直接
	}
	//s.graphics.clear();
	s.graphics.beginFill(c).drawRect(x,y,w,h);
}
//RoundRect Graphics
function graphicRoundRect(s,x,y,w,h,r,color,rainbow,len,no) {
	var c=color;
	if (rainbow) {
		c=createjs.Graphics.getHSL(no/len*360,100,50);//直接
	}
	//s.graphics.clear();
	s.graphics.beginFill(c);operaRoundRect(s,x,y,w,h,r);
}

//quadraticCurveTo
function operaRoundRect(s,x,y,w,h,r) {
	s.graphics.moveTo(x+r,y)
	.lineTo(x+w-r,y)
	.quadraticCurveTo(x+w,y,x+w,y+r)
	.lineTo(x+w,y+h-r)
	.quadraticCurveTo(x+w,y+h,x+w-r,y+h)
	.lineTo(x+r,y+h)
	.quadraticCurveTo(x,y+h,x,y+h-r)
	.lineTo(x,y+r)
	.quadraticCurveTo(x,y,x+r,y);
}

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

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

init();

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


CSS

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


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

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


簡単な説明


Container()インスタンスを作り外周に配置して並べている簡単な作りで、中にShape()インスタンスを収容して、Matrixで外周位置を変化させて回転する仕組みです。「2D」ですので図形の重なりには注意下さい。


1. 通常の Matrix (Matrix2D)で処理しています。
2. 円周配置位置は、matrix変換、transformPoint()を利用しても可能ですが、クセがあるのでここでは使用しません。通常の Matrixで処理したほうが理解し易いでしょう。
3. マウス位置に対応して、回転方向速度が変わります。(マウスイベント解除も可能)
4. 実際には色々と加工して使用する事になると思います。
5. 一応 easeljs-0.7.1でも可動します。


回転速度と位置の計算

tick毎に、回転速度に応じてそれぞれの外周要素の位置を再計算しています。要素の角度も場所により違ってきますので修正します。
ここでの角度補正は、回転方向、要素の角度、などを考慮して再設定しています。角度無しにしますと、回転観覧車のゴンドラの様に成ります。


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

//角度補正
var angle_r=Math.PI/2+cAngle+plusAngle+partsAngle*rotateflag;
//角度無し
//var angle_r=0;

-----------------------------------------------------------
配置角度の計算で半径を違わせれば楕円運動に成る

var radiusX=100;//横方向
var radiusY=50;//縦方向

cx=Math.cos(cAngle+plusAngle)*radiusX;
cy=Math.sin(cAngle+plusAngle)*radiusY;

これは「2D」です、「3D」では有りませんので図形が重なった場合重なりが不自然に成ります。なるべく重ならないように配置下さい。修正方法は在るとは思いますが?..........


Matrix2D

注意点としては、translateの記述の順序によっては、違いがでる場合があるので旨く調整しなければなら無い点くらいである。Matrixの実行は decompose() を使用するところが「AS3」と相違がある。
ガベージコレクション対策として最初にクリア identity() している。


var matrix=new createjs.Matrix2D();
-----------------------------------------------------------
//matrix
matrix.identity();
//translate順序重要
matrix.rotate(angle_r);
matrix.translate(cx,cy);
matrix.decompose(chip[i]);

外周要素はにContainer収容

図形用インスタンス配置コンテナの中に、図形Shapeをいれてあるが、直接Shapeで配置してもよい。ここでは画像などを中に入れる事を想定してコンテナの中に描画している。


デグリー値とラジアン値

Matrix2Dでは「ラジアン値」を使用しますが、初期設定などでは「デグリー値」を使用した方が判りやすいので、途中で変換しています。


CreateJSでは、変換用に、createjs.Matrix2D.DEG_TO_RAD が用意されています。


変換の例

var rotate_angle=angle*createjs.Matrix2D.DEG_TO_RAD;

図形Rolloverによる回転の停止

この「デモ」では設定していませんが、図形要素Rollover時に停止させるならば、図形要素にアクションを設定すれば良い。必要ならば「クリック」アクションなども設定可能である。
実際には、次回(次ぎのページ)で使用して見ます。


var stopNo=1;
-----------------------------------------------------------
//加算/停止処理
plusAngle +=(angle*createjs.Matrix2D.DEG_TO_RAD*stopNo);

-----------------------------------------------------------
//rollover
chip[i].addEventListener("rollover",function () {
	stopNo=0;
});
//rollout
chip[i].addEventListener("rollout",function () {
	stopNo=1;
});

内部図形Shape()

ここでは、内部図形Shape()も配列 innerchip[] にしていますが、実際には何ら制御は行なっていません。


//内部図形
innerchip[i]=new createjs.Shape();

図形graphicsの処理は、モット簡素に出来ますが、以前のものを再利用しています。これはgraphicsの塗り替えも出来る形になっています。


これらの改造などは自由です。


最新のeaseljs-0.8ではMatrixクラスが変更になり、以前のスクリプトは正常に動作しませんのでeaseljs-0.8用に修正しています。詳細は下記記事を参照ください。

【参照】当方の記事: CreateJS Matrixで円周配置の図形Shapeなどを回転(easeljs-0.8)



 

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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]