POPSブログ

CreateJS 「サークルテキスト」アニメーション、レインボー色(虹色)

234

  Category:  javascript2013/07/13 pops 

CreateJSを利用してキャンバス、円周上にレインボー色(虹色)の「サークルテキスト」を表示します。前の「テキストアニメーション」と同じようなものですが、文字を円周上に配置していますが文字間(間隔)がほぼキレイに揃います。アニメーション出来るように考えてみました。
easeljs-0.7 でのテストです。

 

CreateJS 「サークルテキスト」アニメーション、レインボー色(虹色) のテスト


2013/09/25/EaselJSなどバージョンUPされました(easeljs-0.7)。動作など確認してeaseljs-0.7用に更新しています。(2013/10/21)


テキストアニメーションは、AS AS3アニメを書き換えたような感じです。まだ単純ですが、CreateJSのTweenが高性能ですからアレンジが可能と思います。但しブラウザにより「回転精度」「描画品質」が違いますので注意。

 

[説明図]

 

1. 分解した文字を独立させましたので「サークルテキスト」アニメーションが可能です。少々重いのが難点。
ブラウザ、マシン性能で大きな差がでますので注意下さい。
2. 文字は指定色、レインボー色(虹色)どちらも指定出来ます。アニメーションの途中で色を替える事も出来ます。
3. 文字のアニメーション(Tween)は基本的に個人が作成します。現時点ではキャンバス描画テキストは全体的にアニメ品質は良くない。将来改善されるのを期待。
4. 中間の「ロゴ」は png画像です。
5. 静止した「サークルテキスト」も表示しています。(回転及び文字を動かす事は可能)

 

DEMO


CreateJS 「サークルテキスト」アニメーション、レインボー色(虹色) (createJS025.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>
<script type="text/javascript" src="js/tweenjs-0.5.0.min.js"></script>

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


HTML (HTML5)


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

JS

createJS025.js、JS名は任意に変更可。easeljs-0.7用


//日本語
//createJS025.js
//easeljs-0.7記事用
//Circleテキスト rainbow-Color

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

//prologue表示時間
var prologue_time=20000;

//メインテキスト
var mainstring="ViVa POPS WEB KOUBOU - ViVa POPS WEB KOUBOU -";
//サブテキスト
var substring="Kokekokkou Welcome to my site. thanks";

//------------------------------------------------------
//変数、未使用もあり

//ステージ
var stage;
//Object
var canvasObject;
//box
var backrect;
var welcomeImage;
var circlecontainer;
var btncontainer;
//TEXT
var viewtext;

//Circle-TEXT
var circleBase;
var circleflag=false;
//Circle-TEXT2
var circleBase2;

//MAIN-TEXT
var maintextcontainer;
var maintext;
//MOVE-TEXT
var textChip=[];
var textPosx=[];
var textPosy=[];
//MOVEポジション保存
var movePosx=[];
var movePosy=[];
//スケール保存
var keepScale=0;
//回転保存
var keepRote=0;

//SUB-TEXT
var subtextcontainer;
//MOVE-TEXT
var textChip2=[];
var textPosx2=[];
var textPosy2=[];

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

//click-btn
var myhitBtn;
var backchg_no=0;
var backcolors=["#000000","#FFFFFF","#EEEEEE","#888888"];

var clrs=[];
var demo_radius=150;

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

//ステージ周りセット
function init() {

	//STAGE
	stage=new createjs.Stage('mainCanvas');
	//MouseOver重要stage
	stage.enableMouseOver(20);

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

	//クリック
	backrect.addEventListener("click",backchg);
	stage.addChild(backrect);

	//circle-Text circlecontainer
	circlecontainer=new createjs.Container();
	circlecontainer.x=canvasWidth/2;
	circlecontainer.y=canvasHeight/2;
	//ベース2
	circleBase2=new createjs.Container();
	//ベース
	circleBase=new createjs.Container();
	circlecontainer.addChild(circleBase2,circleBase);
	stage.addChild(circlecontainer);

	//welcome画像層画像表示welcome_black.png
	welcomeImage=new createjs.Bitmap('/main/images/textimg01.png');
	welcomeImage.regX=340/2;
	welcomeImage.regY=50/2;
	welcomeImage.x=canvasWidth/2;
	welcomeImage.y=canvasHeight/2-15;
	stage.addChild(welcomeImage);
	//
	stage.update();

	//簡易TEXT、Arialに変更
	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);

	//SUB-TEXT
	subtextcontainer=new createjs.Container();
	stage.addChild(subtextcontainer);

	//btncontainer
	btncontainer=new createjs.Container();
	btncontainer.y=270;
	stage.addChild(btncontainer);
	set_btn();
	myhitBtn.visible=false;

	stage.update();

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

	//調整
	setTimeout(function() {

		//プロローグ表示に進む
		set_prologue();

	},2000);

}

//プロローグ
function set_prologue() {

	//DEMO位置決定
	var xpos_no=Math.floor(Math.random()*3)-1;
	var ypos_no=Math.floor(Math.random()*3)-1;
	circlecontainer.x=canvasWidth/2+xpos_no*100;
	circlecontainer.y=canvasHeight/2+ypos_no*100;
	//DEMO大きさ
	demo_radius=canvasHeight/2+40*Math.floor(Math.random()*3);

	//静止サークルテキスト作成
	set_circletext_pi();
	//サークルテキストアニメ作成
	set_circletext();
	//SUBテキストアニメ作成
	set_subanime();

	//調整
	setTimeout(function() {

		//案内
		set_text("CLICK「ボタン」");
		//ボタン表示
		myhitBtn.visible=true;
		//自動
		//reset_text();

	},prologue_time);
}

//背景色変更
function backchg() {
	backchg_no ++;
	if (backchg_no > backcolors.length-1) {backchg_no=0;}
	var color=backcolors[backchg_no];
	backrect.graphics.beginFill(color).drawRect(0,0,canvasWidth,canvasHeight);
}

//サークルテキスト sin cos で配置した場合PIで計算
function set_circletext_pi() {

	//サークルテキスト
	var text_W=0;
	var text_spc=0;//テキストスペース

	var tChip=[];
	var tPosx=[];
	var tPosy=[];

	var radius=demo_radius-45;//サークル半径
	var circlestring=mainstring+" ";//文字補正空白いれる

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字20px
	tChip=createMoveText("20px","Arial","#777777",false,text_spc,circlestring);
	var textlen=circlestring.length;

	//全幅
	text_W=0;
	for (var i=0; i < textlen; i++) {
		//ポジション取得
		tPosx[i]=tChip[i].x;
		tPosy[i]=tChip[i].y;

		text_W +=tChip[i].width;
		if(i < textlen) {text_W +=text_spc;}

	}

	var twrap=[];
	var angle;

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

		//PIで計算
		angle=Math.PI*2*tPosx[i]/text_W;
		//WRAP
		var wrap=new createjs.Container();

		//半径radius
		wrap.x=Math.sin(angle)*radius;
		wrap.y=Math.cos(angle)*radius;
		wrap.rotation=rotation=(tPosx[i]/text_W*360*-1);//角度修正

		tChip[i].x=0;
		tChip[i].y=0;
		tChip[i].rotation=0;//角度0

		//addChild
		wrap.addChild(tChip[i]);
		twrap[i]=wrap;

		//addChild circleBase2
		circleBase2.addChild(twrap[i]);

	}
	stage.update();
}


//サークルテキストアニメ/現在使用
function set_circletext() {

	var text_spc=0;//テキストスペース

	var radius=demo_radius;//サークル半径
	var circlestring=mainstring+" ";//文字補正空白いれる
	//ベース
	circleBase=new createjs.Container();
	circlecontainer.addChild(circleBase);

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字
	textChip=createMoveText("50px","Impact","#FF0000",false,text_spc,circlestring);
	var textlen=circlestring.length;

	//全幅
	text_W=0;
	for (var i=0; i < textlen; i++) {
		//ポジション取得
		textPosx[i]=textChip[i].x;
		textPosy[i]=textChip[i].y;

		text_W +=textChip[i].width;
		if(i < textlen) {text_W +=text_spc;}

	}

	var sh=textlen-1;
	var k=0;
	var flag=-1;
	var angle=0;
	var textwrap=[];
	var scale_v=0;//スケール
	var alpha_v=1;//alpha

	//多目的用
	var chgflag=Math.floor(Math.random()*3);
	var chgflag2=Math.floor(Math.random()*3);
	var chgflag3=Math.floor(Math.random()*3);
	//逆転フラグ
	var chg_v=Math.floor(Math.random()*2);
	if (chg_v < 1) {chg_v=-1;}

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

		angle=textPosx[i]/text_W*360;//360
		//WRAP
		var wrap=new createjs.Container();
		wrap.regX=0;
		wrap.regY=radius;
		wrap.x=0;
		wrap.y=0;
		wrap.rotation=angle;//angle;
		textChip[i].x=0;
		textChip[i].y=0;

		//移動
		textChip[i].x=0;//0
		textChip[i].y=radius*1.5;//中心から
		if (chgflag == 1) {textChip[i].y=-radius*1.5;}//外から
		if (chgflag == 2) {textChip[i].y=radius*flag*1.5;}//交互

		//識別ID登録
		textChip[i].id=i;

		//スケール変化
		if (chgflag2 == 1) {scale_v=5;alpha_v=0;}

		textChip[i].scaleX=scale_v;//0
		textChip[i].scaleY=scale_v;//0
		textChip[i].rotation=360*(chgflag3-1);//0
		textChip[i].alpha=alpha_v;//1

		//ここでテキスト着色もできる
		//textChip[i].color=createjs.Graphics.getHSL(i/textlen*360,75,75);

		//addChild
		wrap.addChild(textChip[i]);
		textwrap[i]=wrap;

		//addChild
		circleBase.addChild(textwrap[i]);

		k ++;
		flag *=-1;
	}

	//クリア
	clrs=[];

	//circleテキストアニメーション
	//反転フラグY軸
	var roll_y=Math.floor(Math.random()*2);
	if (roll_y < 1) {roll_y=-1;}

	//Tween
	for (var i=0; i < textlen; i++) {
		//色配列代入
		clrs[i]=createjs.Graphics.getHSL(i/textlen*360,75,75);
		//Tween
		var twn3=createjs.Tween.get(textChip[i])
		.wait(300*i)
		.to({x:0,y:0,scaleX:1,scaleY:1*roll_y,rotation:0,alpha:1},1000)
		.call(r_colorchg)
		.wait(100)
		.to({scaleX:2,scaleY:2},400)
		.to({scaleX:1,scaleY:1},400)
		.call(finshmove3);//現在何もしない
	}

	//回転
	circleflag=true;
	stage.update();
}

//途中で色がえ
function r_colorchg() {
	//識別ID
	var id=this.id;
	//THIS
	this.color=clrs[id];
}

//サークルテキストアニメ標準/未使用
function set_circletext_st() {

	var text_spc=0;//テキストスペース

	var radius=canvasHeight/2*.8;//サークル半径
	var circlestring=mainstring+" ";//文字補正空白いれる
	//ベース
	circleBase=new createjs.Container();
	circlecontainer.addChild(circleBase);

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字
	textChip=createMoveText("32px","Arial","#CCCCCC",true,text_spc,circlestring);
	var textlen=circlestring.length;

	//全幅
	text_W=0;
	for (var i=0; i < textlen; i++) {
		//ポジション取得
		textPosx[i]=textChip[i].x;
		textPosy[i]=textChip[i].y;

		text_W +=textChip[i].width;
		if(i < textlen) {text_W +=text_spc;}
	}

	var k=0;
	var flag=-1;
	var angle=0;
	var textwrap=[];

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

		angle=textPosx[i]/text_W*360;//360展開
		//WRAP
		var wrap=new createjs.Container();
		wrap.regX=0;
		wrap.regY=radius;
		wrap.x=0;
		wrap.y=0;
		wrap.rotation=angle;//angle;
		textChip[i].x=0;
		textChip[i].y=0;

		//移動
		textChip[i].x=0;//0
		textChip[i].y=radius;//中心から
		//識別ID登録
		textChip[i].id=i;

		textChip[i].scaleX=0;//0
		textChip[i].scaleY=0;//0
		textChip[i].rotation=0;//0
		textChip[i].alpha=1;//1

		//addChild
		wrap.addChild(textChip[i]);
		textwrap[i]=wrap;
		//addChild
		circleBase.addChild(textwrap[i]);

		k ++;
		flag *=-1;
	}

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn=createjs.Tween.get(textChip[i])
		.wait(300*i)
		.to({x:0,y:0,scaleX:1,scaleY:1,rotation:0,alpha:1},1000);
	}

	//回転
	circleflag=true;
	stage.update();
}

//SUBテキストアニメ
function set_subanime() {

	//SUBテキストアニメーション
	var text_W=0;
	var text_spc=0;//テキストスペース
	var center=true;
	var tcount=0;

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字
	textChip2=createMoveText("20px","Arial","#BBBBBB",false,text_spc,substring);
	var textlen=substring.length;

	//全幅計算
	for (var i=0; i < textlen; i++) {
		//全幅
		text_W +=textChip2[i].width;
		if(i < textlen) {text_W +=text_spc;}
	}
	//コンテナ中央
	if (center) {subtextcontainer.x=(canvasWidth-text_W)/2;}
	subtextcontainer.y=180;

	//パターン番号
	var pattern_no=Math.floor(Math.random()*3);

	//多目的判定用フラグ
	var chgxyflag=Math.floor(Math.random()*5);
	//多目的用2
	var chgflag=Math.floor(Math.random()*3);
	var chgflag2=Math.floor(Math.random()*3);
	//逆転フラグ
	var chg_v=Math.floor(Math.random()*2);
	if (chg_v < 1) {chg_v=-1;}

	//移動
	var k=0;
	var flag=-1;

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

		//addChild
		subtextcontainer.addChild(textChip2[i]);
		//ポジション取得
		textPosx2[i]=textChip2[i].x;
		textPosy2[i]=textChip2[i].y;
		textChip2[i].alpha=0;

		//移動左右
		if (pattern_no == 0) {
			textChip2[i].x +=canvasWidth/2*chg_v*(chgflag+1);
			textChip2[i].y=textPosy[i];//その場
			if (chgflag == 1) {
				textChip2[i].x *=flag;//左右交互
			}
		}
		//移動上下
		if (pattern_no == 1) {
			textChip2[i].x=textPosx2[i];//その場
			textChip2[i].y +=canvasHeight/2*chg_v*(chgflag+1);
			if (chgflag == 1) {
				textChip2[i].y *=flag;//上下交互
			}
		}
		//ランダム
		if (pattern_no == 2) {
			//globalToLocal
			var point=subtextcontainer.globalToLocal(Math.random()*canvasWidth,Math.random()*canvasHeight);
			textChip2[i].x=point.x;
			textChip2[i].y=point.y;
		}

		k ++;
		flag *=-1;
	}

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn2=createjs.Tween.get(textChip2[i])
		.wait(250*i)
		.to({x:textPosx2[i],y:textPosy2[i],alpha:1},1000)
		.call(finshmove2);//色フィルター
	}

}

//MOVEテキストインスタンスを作る
function createMoveText(size,font,color,rainbow,space,str) {

	var fontdata=size + " " + font;

	var chip=[];
	var len=str.length;
	var tpos_x=0;
	var tpos_y=0;

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

		//文字インスタンスを作る
		var t=new createjs.Text(str.charAt(i),fontdata,color);
		//1文字入れる
		//t.text=str.charAt(i);
		//幅高さ
		var w=t.getMeasuredWidth();
		var h=t.getMeasuredHeight();
		//原点中央
		t.regX=w/2;
		t.regY=h/2;
		//虹色
		if (rainbow) {
			t.color=rainbowColor(i,len,100,50);//rainbow
			//t.color=createjs.Graphics.getHSL(i/len*360,100,50);//直接
		}
		//位置
		tpos_x +=w/2;//half
		t.x=tpos_x;
		t.y=tpos_y;//0
		//位置加算
		tpos_x +=(w/2+space);//half+space
		//大きさ重要
		t.width=w;
		t.height=h;
		//
		chip[i]=t;
	}
	//戻り配列
	return chip;
}
//終了
function finshmove () {
	//
}
//終了2
function finshmove2 () {
	this.color="#FFFFFF";
	//shadowフィルター
	this.shadow=shadow;
}
//終了3
function finshmove3 () {
	//
}

//reset_text
function reset_text() {

	set_text("クリア");
	myhitBtn.visible=false;

	circleflag=false;

	//コンテナの中を削除
	circleBase2.removeAllChildren();
	circleBase.removeAllChildren();
	subtextcontainer.removeAllChildren();
	stage.update();

	//調整
	setTimeout(function() {
		set_text("ランダムアニメ実行中");
		set_prologue();
	},2000);

}

//tickステージ
function tick() {
	//circle左巻き回転
	if (circleflag) {
		circleBase.rotation -=0.5;
	}
	stage.update();
}
//VIEWTEXT
function set_text(t) {
	viewtext.text=t;
}

//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);
}

//rainbow-Color2
var rainbowColor=function(v,cv,saturation,lightness) {
	var no=v/cv*360;
	var color=createjs.Graphics.getHSL(no,saturation,lightness);
	return color;
}

//create-text未使用
function create_text(size,font,color,string) {

	var fontdata=size + " " + font;
	var t=new createjs.Text("",fontdata,color);
	t.text=string;
	var w=t.getMeasuredWidth();
	var h=t.getMeasuredHeight();
	//大きさ設定、受け渡しに重要
	t.width=w;
	t.height=h;
	//原点中央
	t.regX=w/2;
	t.regY=h/2;
	return t;

}
//Create-Bottunボタンを作る
function set_btn() {

	//ラベル文字生成
	var label="CLICK";
	//x,y,w,h,r,c,label,lc,overc,outc
	myhitBtn=createbtn (0,0,60,20,5,"#FFFFFF",label,"#FF0000","#48D1CC","#FFFFFF");
	myhitBtn.cursor="pointer";
	myhitBtn.x=(canvasWidth-60)/2;
	myhitBtn.y=0;
	//クリック
	myhitBtn.addEventListener("click",reset_text);
	//addChild
	btncontainer.addChild(myhitBtn);

}

//create-bottunベタ塗り
function createbtn (x,y,w,h,r,c,label,lc,overc,outc) {

	//BTNコンテナ
	var btn=new createjs.Container();
	btn.x=x;
	btn.y=y;
	var s=new createjs.Shape();
	//角丸
	s.graphics.s(0).beginFill(outc);
	operaRoundRect(s,x,y,w,h,r);
	btn.addChild(s);
	//myBtn shadow onMouseOverでupdate()すると濃くなる
	//テキスト以外で使用は注意
	btn.shadow=shadow;
	var tx=new createjs.Text(label,"12px Arial",lc);
	tx.x=w/2;
	tx.y=3;
	tx.maxWidth=w;
	//tx.lineWidth=w;
	tx.textAlign="center";
	tx.shadow=shadow;//テキストは濃くなら無い
	tx.name="btntext";//name挿入
	btn.addChild(tx);
	//文字の食み出し防止mask
	tx.mask=s;

	//rollover
	btn.addEventListener("rollover",function () {
		s.graphics.clear();
		//角丸
		s.graphics.s(0).beginFill(overc);
		operaRoundRect(s,x,y,w,h,r);
		stage.update();
	});
	//rollout
	btn.addEventListener("rollout",function () {
		s.graphics.clear();
		//角丸
		s.graphics.s(0).beginFill(outc);
		operaRoundRect(s,x,y,w,h,r);
		stage.update();
	});
	return btn;
}

//START
init();

注釈文を削除すれば、幾分早くなります。

easeljs-0.7より イベント関連処理が変更になりましたので修正しました。


CSS

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


/*日本語 createJS025.css*/

#demo-wrap {
position:relative;
width:auto;
height:320px;
text-align:center;
}

#image-box {
/*position:absolute;*/
position:relative;
top:0;left:0;
width:640px;
height:300px;
padding:0;
margin:0 auto;
box-shadow:0 0 10px #000;
-moz-box-shadow:0 0 10px #000;
-webkit-box-shadow:0 0 10px #000;
-o-box-shadow:0 0 10px #000;
-ms-box-shadow:0 0 10px #000;
background-color:#000000;
}

#image-box #mainCanvas {
border-radius:10px;
}

.radius {
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
-o-box-border-radius:10px;
-ms-border-radius:10px;
}

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


簡単な説明


テキスト文字を分解インスタンス化して配列で返す

[説明図]

 

テキスト文字の分解組み立ては、1文字ずつ取り出しTextクラスのインスタンスを作り、中心補正して並べて行く作業になります。上図の様な方法です。
詳細は、前のページを参照下さい。


【参照】当方の記事: CreateJS テキストアニメーション ランダム設定のテスト レインボー色(虹色)


テキスト文字を円周上に配置する

基本的に、文字を横に並べて行くのと原理は同じですが、「テキストアニメーション」をし易くするために wrap して中の「テキスト要素」の X Y位置、角度を 0 にしているのが特徴です。wrapに回転角度を与え「テキスト要素」のTweenを容易にさせます。


[説明図]

 

以下の方法はワタシの Flash MX (as) でのテキストアニメ手法をCreateJS形式に変えたものである。上の説明図は概略的なものです。今回は文字のインスタンスを作る所を 別関数化 して。複数の文字列を扱えるようにしました。

原則wrapで半径が決まりますが、「テキスト要素」Y位置調整で円の半径を変えることが可能です。「テキスト要素」をグラフイック(または画像)にすれば図形のアニメーションにも応用できます。(外周配置の文字間隔バランスは、余り気にならない程度バラ付きが有ります)


1. テキスト文字を円周上に配置する際の文字間隔を角度に替えているだけです。
2. テキストアニメーションは通常の角度、(degree)で計算しました。
3. 静止サークルテキストはMath.PI方式、(radian)で計算しました。
文字の初期配置位置に違いが有ります。修正の必要があればそれなりの処理をします。
4. wrapの半径radiusで「テキスト要素」が外周に配置されます。「テキスト要素」Y位置を調整することにより集合離散できます。全てが円の中心に向かいますのでキレイです。
5.「テキスト要素」の角度は 0 ですからTweenさせる場合に楽になります。動きは好み次第に設計できます。
6. 問題は文字の品質がブラウザで違い、外周を円運動させた場合重くなることです。出来れば円運動はさせない方が良い。Chromeでは描画品質が特に悪い!。
(Firefox Safari Chrome 以外で「マシン性能が良い」場合(IE9 Opera)は問題は無いが、この点1-2年待たねば成らない?(MAC Safariは未確認)
7. DEMOではアニメ「サークルテキスト」文字を「Impact」にしています。無き場合は「Arial」など使用されると思います。文字の種類の指定は反映されるとは限りません。
8. ベースをコンテナ(circlecontainer)に入れていますが直接ステージに配置しても良い。


描画品質のキャプチャー図

ブラウザ、マシン性能で差が大きいので、円運動させるレベルではないような気がする。文字数、半径が小さいならば少しは軽くなるかも?。
図の文字は「Arial」より太い「Impact」です。


実際のテキスト配置と円運動

円運動するものしないもの、2種類用意しましたが、どちらも事前のTweenなどの処理を行えます。degree、radian計算などの違いが有りますが中の「テキスト要素」の原点 XY、角度 0 です。

「テキスト要素」を作った場合に「テキスト」のX位置が横並び配置の状態ですので、一旦位置情報を保存して、x=0 の修正をしています。


サークルテキストアニメ標準形

大体の処理標準であるこれをアレンジすれば良い。回転する set_circletext() はこれを原型に作られている。

注意、360度に展開させた場合のバランスのため、文字列の最後に「半角スペース」を入れています。


//サークルテキストアニメ/標準
function set_circletext_st() {

	var text_spc=0;//テキストスペース

	var radius=canvasHeight/2*.8;//サークル半径
	var circlestring=mainstring+" ";//文字補正空白いれる
	//ベース
	circleBase=new createjs.Container();
	circlecontainer.addChild(circleBase);

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字列
	textChip=createMoveText("32px","Arial","#CCCCCC",true,text_spc,circlestring);
	var textlen=circlestring.length;

	//全幅
	text_W=0;
	for (var i=0; i < textlen; i++) {
		//ポジション取得
		textPosx[i]=textChip[i].x;
		textPosy[i]=textChip[i].y;

		text_W +=textChip[i].width;
		if(i < textlen) {text_W +=text_spc;}
	}

	var k=0;
	var flag=-1;
	var angle=0;
	var textwrap=[];

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

		angle=textPosx[i]/text_W*360;//360展開
		//WRAP
		var wrap=new createjs.Container();
		wrap.regX=0;
		wrap.regY=radius;
		wrap.x=0;
		wrap.y=0;
		wrap.rotation=angle;//angle;
		textChip[i].x=0;
		textChip[i].y=0;

		//移動
		textChip[i].x=0;//0
		textChip[i].y=radius;//中心から
		//識別ID登録
		textChip[i].id=i;

		textChip[i].scaleX=0;//0
		textChip[i].scaleY=0;//0
		textChip[i].rotation=0;//0
		textChip[i].alpha=1;//1

		//addChild
		wrap.addChild(textChip[i]);
		textwrap[i]=wrap;
		//addChild
		circleBase.addChild(textwrap[i]);

		k ++;
		flag *=-1;
	}

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn=createjs.Tween.get(textChip[i])
		.wait(300*i)
		.to({x:0,y:0,scaleX:1,scaleY:1,rotation:0,alpha:1},1000);
	}

	//回転
	circleflag=true;
	stage.update();
}

ポジション設定などの注意点

前ページの、横並びの文字作成関数 createMoveText() をそのまま利用していますので、「テキスト要素」の x y 情報を配列に取り込み、その後 x=0 y=0 にしています、これはアニメをやり易くするためです。
現在文字を全周(360度)に配置していますが、展開する角度を指定して配置も可能です。(180度 240度)


//ポジション取得
textPosx[i]=textChip[i].x;
textPosy[i]=textChip[i].y;

//x=0 y=0
textChip[i].x=0;
textChip[i].y=0;

静止サークルテキスト

サンプルとして表示しているだけですが、計算をradianで行っていますので、初期の第一目の文字の位置が3時の方向から描画されます。アニメーションをさせていませんが可能です。
第一文字がずれていますが、第一文字の「x 位置分」(幅の半分)を修正していけば12時方向丁度に成ります。(文字作成関数 createMoveText()が横並び文字用であるので、でずらしています)


SUBテキストアニメ

単に複数の文字列も操作出来ますの例である。文字を左右、上下、ランダム位置、に移動しているだけ。説明などは省略します。


回転品質などについて

AS3でも、上記の方法では回転品質が良く有りませんが、遠近手法など使用すれば良くなると思います(AS3では良くなった)。CreateJSがまだ完全に対処して居ない様だし技術的にワタシはまだ、、、回転させなければ余り問題は起きない。少し時間が経過したらよくなる方法が見つかるかも?


使用画像

340x50 陰影付き、png画像

 

その他

DEMO専用です。使用する事は可能ですが、あくまでもテストですので個人の判断で使用下さい。画像などは各自ご用意下さい。JSの先頭部分をお読み下さい。
但し、効率的な方法があれば、予告無くスクリプトなど修正する場合があります、ご了承下さい。


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]