POPSブログ

CreateJS MotionGuidePlugin を利用した複合、組み合わせ、テキストアニメーションの一例です

241

  Category:  javascript2013/08/12 pops 

CreateJS MotionGuidePlugin による「テキストアニメーション」のシミュレーションで取得した「パスデータ」を実際に組み込んだ例ですが、3種類の違った動きのテキストを表示します。一応判り易いように簡単に作りますが、、、。
easeljs-0.7 でのテストです。

 

CreateJS MotionGuidePlugin 利用して、テキストアニメーションを作る一例 2


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


原則、シミュレーションで「パスデータ」を取得した場合の組み込みの例です。
取得「パスデータ」を使用した、簡単なテキストアニメーションの例ですが、前頁掲載のデモと違い「パスデータ」をX軸、Y軸反転させて複雑な動きにしています。


[説明図]

 

1. パスは前頁掲載のものと同じで、標準のパス(シミュレーションの)の最終ポイントをずらしただけの簡単なものです。(x=500,y=-150)、組み合わせなど少々複雑になっています。
2. 最後のポイント位置によっては、予想のつかない動きをしますので、色々な動きがほしい場合に有効かも知れない?。1つのパスデータでも動きが多彩です。
3. MotionGuide使用テキストアニメ、通常のテキストアニメ、タイピングアニメの3種類組み合わせ。


DEMO


CreateJS MotionGuidePlugin 利用のテキストアニメーションの例 2 (createJS030b.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

createJS030b.js、JS名は任意に変更可。説明用のため一応極単純にしています。easeljs-0.7用


//日本語
//createJS030b.js
//easeljs-0.7用MotionGuideアニメーション
//rainbow-Color

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

//ガイド設定、ポイント固定として
//ガイド幅
var guide_w=500;
//ガイド高さ
var guide_h=-150;

//ポイント固定 true false
var movePoint=true;
//ポイント固定移動をランダムに true false
var randomPoint=false;//true は上のポイント固定は無効になる

//MAIN-TEXT間隔の基準時間//100-250
var base_time=200;
//交互遅延時間 500-1000
var delayed_time=1000;

//メインテキスト
var mainstring="ViVa POPS WEB KOUBOU";
//サブテキスト
var substring="Poyoyouun! Welcome to my site. thanks";
//サブテキスト2
var substring2="CreateJS テキストの複合アニメーション.パスに沿ってMotionTween位置指定";

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

//交換テキスト
startext=["★","☆","△","●",".","+"];

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

//Plugin読み込み
createjs.MotionGuidePlugin.install();

//変数、未使用もあり

//ステージ
var stage;
//コンテナなど
var backrect;
var welcomecontainer;
var subtextcontainer;
var maintextcontainer;
var typingcontainer;
var welcomeImage;
var maintext;
//TEXT
var viewtext;

//配列など
//MAIN-TEXT
var textChip=[];
var textPosx=[];
var textPosy=[];
//MOVEポジション保存
var movePosx=[];
var movePosy=[];
//スケール保存
var keepScale=0;
//回転保存
var keepRote=0;
//SUB-TEXT
var textChip2=[];
var textPosx2=[];
var textPosy2=[];
//MOVEポジション保存
var movePosx2=[];
var movePosy2=[];

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

//グローバル変数など
//サークル用グローバル変数
var partscount=0;
//テキスト用グローバル変数
var textmax=0;
var textcount=0;
var textmax2=0;
var textcount2=0;
//全て終了グローバル変数
var allcount=0;

var test_type="scale";
//Timer
var timerId=null;
var timecount=0;

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

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

var backchg_no=0;
var backcolors=["#000000","#FFFFFF","#778899","#BC8F8F","#20B2AA"];//背景色


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

	//STAGE
	stage=new createjs.Stage('mainCanvas');

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

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

	//welcome画像非表示/isanda.png
	welcomecontainer=new createjs.Container();
	welcomecontainer.x=canvasWidth/2;
	welcomecontainer.y=canvasHeight/2-70;
	welcomeImage=new createjs.Bitmap("/main/images/isanda.png");
	welcomeImage.regX=320/2;
	welcomeImage.regY=32/2;
	welcomecontainer.addChild(welcomeImage);
	welcomeImage.visible=false;
	stage.addChild(welcomecontainer);

	//SUB-TEXT
	subtextcontainer=new createjs.Container();
	//位置
	subtextcontainer.x=0;
	subtextcontainer.y=200;
	stage.addChild(subtextcontainer);

	//MAIN-TEXT
	maintextcontainer=new createjs.Container();
	//位置中央/あとで修正される
	maintextcontainer.x=canvasWidth/2;
	maintextcontainer.y=canvasHeight/2;
	stage.addChild(maintextcontainer);

	//typingcontainer
	typingcontainer=new createjs.Container();
	typingcontainer.y=50;
	stage.addChild(typingcontainer);

	//簡易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);
	set_text("START");

	stage.update();

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

	//調整
	setTimeout(function() {

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

	},2000);

}

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

	//全て終了グローバル変数
	allcount=0;//クリア
	set_text("START");

	//MAIN-TEXT
	set_mainanime();

	//調整、文字は少し遅れて描画
	setTimeout(function() {

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

		//tipo
		typing_text();

	},2000);

}

//MAINテキストアニメ、ガイド使用
function set_mainanime() {

	set_text("ANIMATION");

	textcount=0;//カウント、グローバル

	textChip=[];//クリア
	//MAINテキストアニメーション
	var maintext_W=0;
	var text_spc=0;//テキストスペース
	var center=true;

	//インスタンス配列取得
	//サイズ,フォント,色,虹色,スペース,文字
	textChip=createMoveText("40px","Arial","#FFFFFF",true,text_spc,mainstring);
	var textlen=mainstring.length;
	//テキスト用グローバル変数
	textmax=textlen;

	//全幅の計算を先に計算
	for (var i=0; i < textlen; i++) {
		maintext_W +=textChip[i].width;
		if(i < textlen) {maintext_W +=text_spc;}

	}
	//コンテナ中央補正
	if (center) {maintextcontainer.x=(canvasWidth-maintext_W)/2;}

	//ランダム移動値を作る、コンテナ中央補正のあとで作ること
	//ランダム移動値保存容器
	var radpos_x=[];
	var radpos_y=[];

	for (var i=0; i < textlen; i++) {
		//ランダム移動値を保存
		//globalToLocal
		var point=maintextcontainer.globalToLocal(Math.random()*canvasWidth,Math.random()*canvasHeight);
		radpos_x[i]=point.x;
		radpos_y[i]=point.y;
	}

	//randomPointランダムの処理
	if (randomPoint) {
		var mp=Math.floor(Math.random()*2);
		movePoint=false;
		if (mp == 1) {movePoint=true;}
	}

	//delay容器
	var delay_st=[];
	//パターン番号/拡張用、未使用
	var pattern_no=Math.floor(Math.random()*10);

	//多目的判定用フラグ
	var chgxyflag=Math.floor(Math.random()*5);
	//多目的用2
	var chgflag=Math.floor(Math.random()*3);
	var chgflag2=Math.floor(Math.random()*3);
	var chgflag3=Math.floor(Math.random()*3);//ガイド用
	var star_v=Math.floor(Math.random()*startext.length);//星の種類番号

	//逆転フラグ
	var chg_v=Math.floor(Math.random()*2);
	if (chg_v < 1) {chg_v=-1;}

	//回転
	var rotate_no=chgflag*chg_v;
	//スケール
	var sclsdata=[1,1,1,0,.5,4,8,12];
	var scls=sclsdata[Math.floor(Math.random()*sclsdata.length)];

	//delay番号
	var delay_no=Math.floor(Math.random()*4);

	//ガイド幅を変える100% 50% 33%
	var guide_w2=Math.round(guide_w/(chgflag3+1));

	//ガイドreverse反転/mutual交互
	var mutual=false;
	var reverse_v=1;
	if (chgflag3 == 1) {reverse_v=-1;}//反転
	if (chgflag3 == 2) {mutual=true;reverse_v=1;}//交互
	//半径
	var radius=canvasHeight/2;
	//alphaの調整
	var alpha_no=0;
	if (scls < 0.2) {alpha_no=1;}

	var sh=textlen-1;
	var k=0;
	var flag=-1;

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

		//ID
		textChip[i].id=i;
		//addChild
		maintextcontainer.addChild(textChip[i]);
		//ポジション取得
		textPosx[i]=textChip[i].x;
		textPosy[i]=textChip[i].y;

		//yはパス最後で反転しているのでそのまま
		//ポイント固定、xそのまま
		if (movePoint) {
			textChip[i].x=guide_w2;
			textChip[i].y=guide_h;
		}
		//ポイント移動、x反転あり
		if (!movePoint) {
			textChip[i].x=(guide_w2+textPosx[i])*reverse_v;
			textChip[i].y=guide_h;
		}

		//MOVEポジション保存
		movePosx[i]=textChip[i].x;
		movePosy[i]=textChip[i].y;
		//スケール保存
		keepScale=scls;
		//回転保存逆転あり
		keepRote=rotate_no*180*(chgflag2-1);

		//セット
		textChip[i].rotation=keepRote;
		textChip[i].alpha=alpha_no;//調整
		textChip[i].scaleX=scls;
		textChip[i].scaleY=scls;

		//共通delay
		delay_st[i]=base_time*i;//標準

		if (delay_no == 0) {delay_st[i]=base_time*(sh-i);}//逆順
		if (delay_no == 1) {delay_st[i]=Math.abs(i-sh/2)*base_time;}//中から
		if (delay_no == 2) {delay_st[i]=Math.abs(Math.abs(i-sh/2)-textlen/2)*base_time;}//外から

		//交互遅延
		if (chgflag2 == 1) {
			if (flag == 1) {delay_st[i] +=delayed_time;}
		}

		k ++;
		flag *=-1;
	}

	//delayの最大値を求める
	var max_delay=Math.max.apply(null,delay_st);
	//speed
	var speed_v=2000;

	var flag=-1;
	//Tween
	for (var i=0; i < textlen; i++) {

		if (mutual) {reverse_v *=flag;}//ガイド波形交互

		//Tween
		var twn=createjs.Tween.get(textChip[i]);

		twn.wait(delay_st[i])
		.to({guide:{path:[textPosx[i],textPosy[i], 100*chg_v+textPosx[i],-150*reverse_v,200*chg_v+textPosx[i],0, 300*chg_v+textPosx[i],150*reverse_v, movePosx[i],movePosy[i]*chg_v],orient:false,start:1,end:0},rotation:0,scaleX:1,scaleY:1,alpha:1},2000)//左右用
		.to({x:textPosx[i],y:textPosy[i],rotation:0},50);

		twn.wait(50).to({x:textPosx[i],y:textPosy[i]},50)
		.wait(100).to({scaleX:2,scaleY:2},50)
		.wait(100).to({scaleX:1,scaleY:1},200)
		.call(finshmove)//shadow
		.wait(max_delay-delay_st[i])//最大値利用時間差吸収
		.wait(1000)
		.to({y:-20,scaleX:3,scaleY:3,alpha:.5},1000)
		.wait(500)
		.to({y:0,scaleX:1,scaleY:1,alpha:1},800)
		.wait(1000)

		.to({x:radpos_x[i],y:radpos_y[i],scaleX:.1,scaleY:.1,rotation:360*chg_v*flag},800)//ランダム移動値を使用
		.wait(2000)
		.to({x:textPosx[i],y:textPosy[i],scaleX:1.5,scaleY:1.5,rotation:0},2000)
		.to({scaleX:1,scaleY:1},500)

		.wait(5000)
		.to({x:textPosx[i]-canvasWidth*chg_v},600)//左または右に全体移動
		.to({x:textPosx[i]+canvasWidth*chg_v},1)//反対側に瞬間移動
		.wait(1000)
		.to({x:textPosx[i]},800)//元に戻す
		.wait(500)
		.to({scaleX:.5,scaleY:.5},400)
		.to({scaleX:1,scaleY:1},200)
		.wait(5000)
		.to({y:-10,scaleY:0},500)//スケールで消滅
		.to({y:-canvasHeight*.6,scaleY:1,alpha:0},1)//上に瞬間移動
		.wait(1000)
		.to({y:0,alpha:1},1000)
		.wait(5000)
		.wait(delay_st[i])
		.call(finshmove2)//shadow-clear
		.wait(500);

		if (chgflag == 0) {
			twn.to({scaleX:0.1,scaleY:0.1},200)
			.call(makeball,[star_v])//星番号
			.to({scaleX:1,scaleY:1,rotation:360*chg_v},400);
		}

		twn.to({guide:{path:[textPosx[i],textPosy[i], 100*chg_v+textPosx[i],-150*reverse_v,200*chg_v+textPosx[i],0, 300*chg_v+textPosx[i],150*reverse_v, movePosx[i],movePosy[i]*chg_v],orient:false,start:0,end:1},scaleX:keepScale,scaleY:keepScale,alpha:alpha_no,rotation:keepRote},speed_v)
		.call(function(){
			//終了
			if (textcount == textmax-1) {finshtextAll();}
			textcount +=1;//グローバルの事
		});

		flag *=-1;
	}

}

//SUBテキストアニメ、ガイドなし
function set_subanime() {

	textChip2=[];//クリア

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

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

	textmax2=textlen;

	//ランダム配置のため全幅の計算を先に
	for (var i=0; i < textlen; i++) {
		subtext_W +=textChip2[i].width;
		if(i < textlen) {subtext_W +=text_spc;}
	}
	//コンテナ中央補正
	if (center) {subtextcontainer.x=(canvasWidth-subtext_W)/2;}

	//移動
	var delay_st2=[];
	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;

		//ランダム移動
		//globalToLocal
		var point=subtextcontainer.globalToLocal(Math.random()*canvasWidth,Math.random()*canvasHeight);
		textChip2[i].x=point.x;
		textChip2[i].y=point.y;

		//MOVEポジション保存
		movePosx2[i]=textChip2[i].x;
		movePosy2[i]=textChip2[i].y;

		textChip2[i].scaleX=0;
		textChip2[i].scaleY=0;

		//delay
		delay_st2[i]=200*i;

		k ++;
		flag *=-1;
	}

	//delayの最大値を求める
	var max_delay2=Math.max.apply(null,delay_st2);

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn2=createjs.Tween.get(textChip2[i])
		.wait(delay_st2[i])
		.to({x:textPosx2[i],y:textPosy2[i],scaleX:1,scaleY:1},1000)//IN
		.wait(max_delay2-delay_st2[i])//最大値利用時間差吸収
		.wait(20000)
		.wait(delay_st2[i])
		.to({scaleX:1.5,scaleY:1.5},200)
		.to({x:movePosx2[i],y:movePosy2[i],scaleX:0,scaleY:0},1000)//OUT
		.call(function(){
			//終了
			if (textcount2 == textmax2-1) {finshtextAll2();}
			textcount2 +=1;//グローバルの事
		});
	}

}

//1文字ずつ表示
function typing_text () {

	//表示位置指定
	var pos="left";//center left

	//簡易TEXT、Arialに変更
	var typingbox=new createjs.Text("","12px Arial","#CCCCCC");
	typingbox.textBaseline="bottom";
	typingbox.text=substring2;

	//表示位置
	if (pos == 'center') {
		typingbox.textAlign="center";
		typingcontainer.x=canvasWidth/2;
	}
	if (pos == 'left') {
		typingbox.textAlign="left";
		//幅取得
		var tipo_w=typingbox.getMeasuredWidth();
		//var tipo_h=typingbox.getMeasuredHeight();
		typingcontainer.x=(canvasWidth-tipo_w)/2;
	}

	typingbox.text="";
	typingcontainer.addChild(typingbox);

	//重要、カウントクリア
	timecount=0;
	//Timer設定
	timerId=setInterval("tipo()",50);

/*
	//Tick方式これでもOK
	typingbox.tick=function (){
		var len=substring2.length;
		if (timecount < len) {
			typingcontainer.getChildAt(0).text += substring2.charAt(timecount);
		} else {
			removeEventListener('tick',typingbox.tick);
		}
		timecount +=1;
	}
	//Ticker.addEventListener設定
	createjs.Ticker.addEventListener('tick',typingbox.tick);
*/

}
//TIPO表示
function tipo () {
	var len=substring2.length;
	if (timecount < len) {
		typingcontainer.getChildAt(0).text += substring2.charAt(timecount);
	}else {
		clearInterval(timerId);//クリアTimer
	}
	timecount +=1;
}

//テキストshadow
function finshmove() {
	this.shadow=shadow2;
}
function finshmove2() {
	this.shadow=null;
}

//makeballテキスト交換
function makeball(v) {

	//this.text="★";
	this.text=startext[v];
}

//MAINテキスト終了
function finshtextAll () {

	//welcome画像FadeIn
	welcomeImage.alpha=0;
	welcomeImage.y=20;
	welcomeImage.visible=true;
	var twn3=createjs.Tween.get(welcomeImage)
	.to({y:0,alpha:1},600);

	//調整
	setTimeout(function() {

		//subtextインスタンス表示
		//subText.visible=true;

		finshAll();

	},2000);
}
//SUBテキスト終了
function finshtextAll2 () {

	//調整
	setTimeout(function() {

		//TIPOテキストを削除
		typingcontainer.removeAllChildren();
		//typingcontainer.getChildAt(0).text="";

		//全て終了
		finshAll();

	},1000);
}

//全て終了
function finshAll () {

	//全て終了グローバル変数
	allcount +=1;

	//2個のアニメ終了
	if (allcount == 2) {
		//END
		set_text("END");
		//調整
		setTimeout(function() {

		set_text("AUTO");
		//リセット処理
		reset_parts();

		},2000);
	}
}
//reset_parts
function reset_parts() {

	set_text("CLEAR/REMOVE");

	//MAIN-TEXTコンテナの中を削除
	maintextcontainer.removeAllChildren();
	//SUB-TEXTコンテナの中を削除
	subtextcontainer.removeAllChildren();
	//welcome画像非表示
	welcomeImage.visible=false;
/*
	//removeTween
	for (var i=0; i < textmax; i++) {
		createjs.Tween.removeTweens(textChip[i]);
	}
	for (var i=0; i < textmax2; i++) {
		createjs.Tween.removeTweens(textChip2[i]);
	}
*/

	//バージョン4.2.1
	createjs.Tween.removeAllTweens();

	stage.update();
	//調整
	setTimeout(function() {
		set_prologue();
	},2000);

}

//tickステージ
function tick() {
	stage.update();
}

//Starインスタンスを作る
function createStar(x,y,r,color,rainbow,len,no) {
	var c=color;
	if (rainbow) {
		c=createjs.Graphics.getHSL(no/len*360,100,50);//直接
	}
	var s=new createjs.Shape();
	s.graphics.s().beginFill(c).drawPolyStar(0,0,r,5,r/2,-90);
	//原点中央
	s.regX=0;
	s.regY=0;
	return s;
}

//背景色変更
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);
}

//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("",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,80,40);//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;
}

//VIEWTEXT
function set_text(t) {
	viewtext.text=t;
}

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

//START
init();

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


CSS

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


/*日本語 createJS030b.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. パスは標準のパス(シミュレーションの)の最終ポイントをずらしただけの簡単なものです(x=500,y=-150)。
2次ベジェ曲線ですから、それなりの動きになります。固定の場合はパス波形が変わりますのでこの特性を利用すれば新たな動きも可能か?。
2. アニメする場合の速度などの条件で、雰囲気が変わりますので適度に調整します。
3. パス情報を書き込み、文字位置の情報を加算するだけですが、X軸、Y軸反転させています(4種の形になる)。最後を固定しているので、予測の出来ない動きになる場合がある。
4. アニメは IN OUT がありますが、同じパスデータにして、start end で再利用しています。
5. 余り考えず、偶然出来た動きを利用した方が良いかも知れない。イイカゲンに作ったほうがベターだよ。
6. 文字個別にはパスに沿って動いていますが、文字全体でみればパスの形と同形に成るとは限りません。
7. 設定などはJS上部をご覧下さい。


ポイント固定とポイント移動

1. ガイドパスは原点 00 です。そのために文字の配置間隔で「ポイント移動」させることにより同じパスの波形になり、同じ動きになります。この文字の作り方では常に修正が必要です。
2. 一方「ポイント固定」は最後のポイントが同じ所になり、相対的に「2次ベジェ曲線」の制御ポイントが動くので、パスの波形が変わり違った動きをします。(「2次ベジェ曲線」の特性上余りきれいな曲線では有りませんが)
3. デモでは、「ポイント移動」の際にも少々距離を違わせてアレンジしたので、少し違う動きをします。


何気なしに「ポイント固定」してわかったことですが、結構変化を付ける簡単且つ有効手段かも知れません。


デモは、下の「パスDATA」に基づきますが、書き換えなどは以下の順序で行います。


パスDATA

次ぎのようなデータで前ページのものと同じです。


path:[0,0, 100,-150,200,0, 300,150,500,-150]

パス情報の、X軸、Y軸反転

[説明図]


 

パス情報の、X軸、Y軸反転は図のような考えで1つのパスで4つの波形を得ようと言うものだが、終点の y値が 0 でないと処理が面倒になる。
但し、デモではy値の値が0でないため一層予測の出来ない動きをだしている。x値も画面内にあるので一層波形が変わるのでその偶然を利用する考えである。


各々の文字位置は、[textPosx[i],textPosy[i]であるのでそれをパスのポイントに加えてある。但し、textPosy[i]の中は0です。(文字の y原点 は 0 にしている)
上図の様に、X軸、Y軸反転のために、x には chg_v、y には reverse_v を乗じています。値は +1、-1 が与えられるようにしている。つまり反転を制御できる。
最後 movePosx[i],movePosy[i] は移動先の情報である。ここでは、y に chg_v を乗じていますが、特別に変化をつけている。通常は正確な位置情報をいれておくので乗算はしない。(この辺は自由ですが、、)



path:[0,0, 100,-150,200,0, 300,150,500,-150]の数値で補正すると以下のようになる

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

IN
.to({guide:{path:[textPosx[i],textPosy[i], 100*chg_v+textPosx[i],-150*reverse_v,200*chg_v+textPosx[i],0, 300*chg_v+textPosx[i],150*reverse_v, movePosx[i],movePosy[i]*chg_v],orient:false,start:1,end:0},rotation:0,scaleX:1,scaleY:1,alpha:1},2000)//左右用

OUT
twn.to({guide:{path:[textPosx[i],textPosy[i], 100*chg_v+textPosx[i],-150*reverse_v,200*chg_v+textPosx[i],0, 300*chg_v+textPosx[i],150*reverse_v, movePosx[i],movePosy[i]*chg_v],orient:false,start:0,end:1},scaleX:keepScale,scaleY:keepScale,alpha:alpha_no,rotation:keepRote},speed_v)

パスポイントの固定と移動の処理

JS先頭での入力データのガイド幅を変えて変化をつけていますからより複雑な動きをします。
旨く合わない時の対策として、IN OUT 共に大きさを 0 にまたは透明度を 0 にして「アラ」が出ない様する。

無理に色々と合わせるよりも、偶然出来る動きを旨く利用した方が良い。つまり「イイカゲン」と「デタラメ」が重要だ!


最後の位置を変えると、波形も変わるが必ずしもキレイな動きになるとは限らないが、偶然が大事だ。



//ガイド幅を変える100% 50% 33%
var guide_w2=Math.round(guide_w/(chgflag3+1));

//MAINテキストアニメ
function set_mainanime() {

	略す

	//ループ
	for (var i=0; i < textlen; i++) {

		略す

		//yはパス最後で反転しているのでそのまま
		//ポイント固定、xそのまま
		if (movePoint) {
			textChip[i].x=guide_w2;
			textChip[i].y=guide_h;
		}
		//ポイント移動、x反転あり
		if (!movePoint) {
			textChip[i].x=(guide_w2+textPosx[i])*reverse_v;
			textChip[i].y=guide_h;
		}

		略す

	}

	略す

}
------------------------------------------------------------

このデモでは、パスの最後に注意、保存最後位置 yにchg_vを乗算
保存最後位置 xはそのままだ、つまり固定

path:[........, movePosx[i],movePosy[i]*chg_v]


書き換えなどについて

他人のものは判りにくいので、個人が、自由な変数、条件、を作って最初から作り直した方が良い場合もある。アルゴリズムは同じである。


Tweenの変更について

Tweenなどの操作、書き換えなどは自由です。「文字個別」「全文字」のTweenと2種が混同しています。アニメは、wait()で操作されていますのでその制御が重要になります。特に「文字個別」から「全文字」の切り替えのwaitの修正が大事です。
注意は、if文を使用する時にチェーンメソッドが使用できないの(一旦区切りまたチェーンする)でエラーにならないように記載する位だ。
call()も旨く利用すれば応用変化を楽しめる。


文字はwait値が違うため、.wait(max_delay-delay_st[i]) で wait の値を順次 max_delay に変更しているだけの処理です。この辺は「知恵の3番しぼり、デガラシタイプ」のアイデア勝負だ!



delayの事前に最大値を求めておく
//delayの最大値を求める
var max_delay=Math.max.apply(null,delay_st);

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

最大値を利用して時間差をなくすことにより文字全体を制御出来るようにする
.wait(max_delay-delay_st[i])////最大値利用時間差吸収
.wait(1000)

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

文字全体から文字個別の制御は簡単です、全体で5秒まってから
文字個別の操作にしている
.wait(5000)
.wait(delay_st[i])
.call(finshmove2)//shadow-clear



その他


Tween途中での文字の取替え

Tween途中、「テキスト要素」を交換テキスト文字「★」等に取り替えています。(動いている「テキスト要素」は軽量にするため中に Shapeクラス (又はコンテナ) が有りませんので、グラフイックでの取替えが大変難しいので、省略)

よって「★ ☆ △ ●」は「日本語環境」でなければ正しく表示しませんから注意下さい。


Tweenの削除

繰り返し表示しているので、一応、1回の表示毎にTweenの削除を実行してみた。(ここでTweenの削除をすべきか、効果があるかは不明、何となく削除してみただけです)
tweenjsバージョン4.2.1からは一括削除できる removeAllTweens() が使用できるとか。



/*
	//removeTween
	for (var i=0; i < textmax; i++) {
		createjs.Tween.removeTweens(textChip[i]);
	}
	for (var i=0; i < textmax2; i++) {
		createjs.Tween.removeTweens(textChip2[i]);
	}
*/

//バージョン4.2.1
createjs.Tween.removeAllTweens();

removeAllTweens()については、以下、参考にしました。

【参考】fumiononaka.com: TweenJS とSoundJS 0.4.1に備わったインスタンスを削除するメソッド


タイピング風文字

サブテキスト2(substring2)を1文字ずつ表示する「タイピング風文字」にして見た、中央に配置して左よりタイピングするために工夫している。関数 typing_text() 参照。
キャンバスの場合は少しクセがあるようだ。setInterval()を使用しているがあまりこれ(setInterval)は使用したくない。



その都度作っている

//簡易TEXT
var tipingbox=new createjs.Text("","12px Arial","#CCCCCC");

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

Tick方式の場合、これでも動くがsetInterval()を使用

	//Tick方式これでもOK
	typingbox.tick=function (){
		var len=substring2.length;
		if (timecount < len) {
			typingcontainer.getChildAt(0).text += substring2.charAt(timecount);
		} else {
			removeEventListener('tick',typingbox.tick);
		}
		timecount +=1;
	}
	//Ticker.addEventListener設定
	createjs.Ticker.addEventListener('tick',typingbox.tick);

テキスト、typingbox を使い回ししようと思ったが旨く行かずその都度作っている。この辺は?だ。




使用画像

特製、Welcome画像 320x32 陰影付きPNG isanda.png

 

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


テキストアニメーションは、以下の記事を参照下さい。

【参照】当方の記事: CreateJS MotionGuidePlugin 利用して、テキストアニメーションを作る一例です

MotionGuide利用、テキストアニメーションのシミュレーション。

【参照】当方の記事: CreateJS MotionGuide利用、テキストアニメーションのシミュレーション


MotionGuide利用、図形とテキストアニメーション。

【参照】当方の記事: CreateJS 図形テキストをアニメーション、Tween 連続操作と MotionGuideTween の組み合わせ


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]