POPSブログ

CreateJS 画像分割とテキストアニメーションの組み合わせ (最新)

294

  Category:  javascript2014/05/10 pops 

何種類かの 画像分割についての記事は書いてきましたが、少々改良すべき所を修正しています。今回はテキストアニメーション、サムネールボタンと組み合わせて見ました。
easeljs-0.7.1 でのテストです。

 

CreateJS 画像分割とテキストアニメーションの組み合わせ テスト


1. 最新の画像分割です。(見た目は以前と変わりありません)
2. プロローグにテキストアニメーションを組み合わせました。
3. 画像分割の最初にアニメーションのテキストをもキャプチャーして画像として分割。
4. サムネールボタンをつけました。


 

DEMO


CreateJS 画像分割とテキストアニメーションの組み合わせデモ、(createJS078.js)

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


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


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

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


<script type="text/javascript" src="js/easeljs-0.7.1.min.js"></script>
<script type="text/javascript" src="js/preloadjs-0.4.1.min.js"></script>
<script type="text/javascript" src="js/tweenjs-0.5.1.min.js"></script>

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


HTML (HTML5)


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

JS

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


//日本語
//createJS078.js
//最新画像分割デモ用

//------------------------------------------------------
//初期設定

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

var split_free=true;//自動分割 true false
var speed=1200;//拡大移動、アニメ速度
var delay_speed=150;//出現間隔、delay基準時間 100-200

//自動分割でない場合の分割
var split_h=11;//標準の横方向分割数、奇数値
var split_v=5;//標準の縦方向分割数、奇数値
var split_all=split_h*split_v;

//プロローグ
var prologueUse=true;//true false
//prologue調整時間 3000-
var prologue_time=5000;
//
var maintextUse=true;//true false
//メインテキスト
var mainstring="ViVa POPS WEB KOUBOU";
//メインテキスト表示位置
var mtcontainer_x=100;//中央補正しない場合
var mtcontainer_y=120;//使用

//タイマーの使用、useであること
var timer_use="use";
//タイマー値 5000-10000
var time=8000;

//ボタンを作る
var clickbtnUse=true;//true false

//サムネールの大きさ余白
var thumbW=64;
var thumbH=30;
var margin=2;//余白 未使用
//ボタンの大きさ
var btnRadius=5;//角丸半径
var btnSpace=10;//未使用
var interval_W=80;//ボタン間隔
var interval_H=20;//コンテナY位置 stage2上から
//ボタンactiveカラー
var active_color="#20B2AA";

//テキスト表示の使用 use=true
text_use=true;//true false

//自動分割の場合、free分割データを登録/奇数値が良い
//var splitHs=[11,11,11,7];
//var splitVs=[5,5,5,3];
var splitHs=[11,11,11,7,11,7,21,41,1];//縦40以上は注意、修正済み
var splitVs=[5,5,5,3,1,1,1,1,1];

//スケール方向番号データ 0-3
var scales=[0,0,0,0,1,2,3];
//回転データ、余り回転しない、回転は120度x回転データ
var rotates=[0,0,0,0,1,2,3];

//画像manifestリスト
var manifest=[
{src:"/main/images/flight01.jpg",id:"PHOTO1"},
{src:"/main/images/flight02.jpg",id:"PHOTO2"},
{src:"/main/images/flight03.jpg",id:"PHOTO3"},
{src:"/main/images/flight04.jpg",id:"PHOTO4"},
{src:"/main/images/flight05.jpg",id:"PHOTO5"},
{src:"/main/images/flight06.jpg",id:"PHOTO6"}
]

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

//ステージ
var stage,stage2;
//キャンバス
var mainImage;
//コンテナ
var container;
var backcontainer;
var loadingcontainer;
var progresscontainer;
var textcontainer;
var btncontainer;

//ローダー
var loader;
//LoadingShape
var loadingShape;

//読み込み画像の大きさ、未使用
var imageH=0,imageW=0;
//読み込み画像URL保存容器
var assets=[];
//分割大きさ位置保存容器
var chip_W=[],chip_H=[],chip_pos_X=[],chip_pos_Y=[];
//実際配置位置
var set_pos_X=[],set_pos_Y=[];
//移動配置位置
var mov_pos_X=[],mov_pos_Y=[];
//スライスObject容器
var chip=[];

//変数
var globalflag=false,backImage,mainImage,keep_mainImage,timerID=null;
var inType=true;
var moveType="";
var kcount=0
var viewtext;
var once=false;

//サムネールBOX
var thumbBox;//container
var thumbImage;//画像Bitmap
var thumb=false;//サムネール動作判定
var thumb_x=0;//サムネール位置

//ボタンが押された/有効
var btnValidity=false;
//ボタン保存
var myBtn=[];

//loading変数
var loading=false;
//ProgressBar
var progressbar;
var progtext;
var bar_v=0;

//最初の画像0のこと
var image_no=0;
//画像数
var image_max;
//陰影
var shadow=new createjs.Shadow("#000000",0,0,4);

//MAIN-TEXT
var maintextcontainer;
var maintext;
//MOVE-TEXT
var textChip=[];
var textPosx=[];
var textPosy=[];

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

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

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

	//welcome画像層画像表示
	if(backgroundimage) {
		welcomeImage=new createjs.Bitmap(backgroundimage);
		stage.addChild(welcomeImage);
		keep_mainImage=backgroundimage;
	}


	//下画像層、空画像コンテナを作る/寸法設定なくともOK
	backcontainer=new createjs.Container();
	backImage=new createjs.Bitmap();
	backcontainer.addChild(backImage);
	stage.addChild(backcontainer);
	
	//スライス画像層、空コンテナを作る、使いまわし
	container=new createjs.Container();
	stage.addChild(container);

	//TEXT text_useが有効なら作る
	if (text_use) {

		//TEXTコンテナ フィールド00なので中央表示にはならない
		textcontainer=new createjs.Container();
		//textbackShape
		var textback=new createjs.Shape();
		textback.graphics.beginFill("#000000").drawRect(0,0,canvasWidth,25);
		textback.alpha=0.3;
		textback.visible=false;//非表示

		//注意 大きさを設定しないと文字は表示しない
		viewtext=new createjs.Text("---","12px Arial","#FFFFFF");
		viewtext.x=20;
		viewtext.y=18;
		viewtext.lineWidth=canvasWidth-40;
		viewtext.lineHeight=20;
		viewtext.textBaseline="bottom";
		textcontainer.addChild(textback,viewtext);
		stage.addChild(textcontainer);
		//テキスト陰影
		viewtext.shadow=shadow;

		text_set("LOADING NOW");
	}

	//MAIN-TEXTキャプチャーを得るため2重にしている
	if(maintextUse) {
		//コンテナ
		maintextcontainer=new createjs.Container();
		stage.addChild(maintextcontainer);
	}

	//ボタン使用
	if (clickbtnUse) {

		//STAGE2
		stage2=new createjs.Stage('subCanvas');
		//MouseOver重要
		stage2.enableMouseOver(20);
		//ボタンコンテナ
		btncontainer=new createjs.Container();
		//ステージ2にaddChild
		stage2.addChild(btncontainer);
		btncontainer.visible=false;

	}

	//loading3コンテナをステージにaddChild
	loadingcontainer=new createjs.Container();
	stage.addChild(loadingcontainer);
	//ShapeのLOADINGを作る
	loadingShape=loadingIndicator3();
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/2;
	//tickを設定
	loadingShape.tick=function (){
		loadingShape.rotation +=5;

	}
	//loading addEventListenerを設定
	createjs.Ticker.addEventListener('tick',loadingShape.tick);
	//コンテナに貼り付け
	loadingcontainer.addChild(loadingShape);
	loading=true;//loading表示判定未使用

	//ProgressBar
	progresscontainer=new createjs.Container();
	progressbar=new createjs.Shape();
	progtext=new createjs.Text("0","12px Arial","#FFFFFF");
	progtext.x=0;
	progtext.y=15;
	progtext.maxWidth=80;
	progtext.textAlign="center";
	progtext.shadow=shadow;//shadow
	//alpha
	progressbar.alpha=0.5;

	//bar_v判定tickを設定 butt round/Stroke
	//90度是正-Math.PI/2
	progressbar.tick=function (){
		if(bar_v > 0) {
			progressbar.graphics.clear();
			progressbar.graphics.setStrokeStyle(8,"butt").beginStroke("#FF69B4");
			progressbar.graphics.arc(0,0,40,-Math.PI/2,Math.PI*2*bar_v-Math.PI/2);
			progtext.text=Math.floor(bar_v*100);
		}
	}
	//Ticker.Listener設定
	createjs.Ticker.addEventListener('tick',progressbar.tick);
	//addChild
	progresscontainer.x=canvasWidth/2;
	progresscontainer.y=canvasHeight/2;
	progresscontainer.addChild(progressbar,progtext);
	stage.addChild(progresscontainer);

	//Main-Ticker設定
	createjs.Ticker.setFPS(30);
	//createjs.Ticker.timingMode=createjs.Ticker.RAF;
	createjs.Ticker.addEventListener('tick',tick);

	//画像ロードに進む
	bulkload();

}

//progressBar
function progress(event) {

	//loadedのみ効く
	bar_v=event.loaded;
}

//bulk-load、画像一括ロード
function bulkload() {

	//Loader
	loader=new createjs.LoadQueue(false);
	//全体、progressがあれば先に設定
	loader.addEventListener("progress",progress);

	//loader EventListener設定、この部分修正
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);

	//Manifestを使用、manifest読み込み開始
	loader.loadManifest(manifest);

}
//各画像読み込み完了
function fileload (eventObject) {

	//エラー無しの画像をassets容器に保存
	assets.push(eventObject.result);

}
//全ての画像読み込み完了
function complete (event) {

	text_set("LOADING END!");
	//画像数確認、再計算
	image_max=assets.length;

	//loader Listener削除 こちら使用に修正
	loader.removeEventListener("fileload",fileload);
	loader.removeEventListener("complete",complete);

	//loading Listener削除
	createjs.Ticker.addEventListener('tick',loadingShape.tick);
	//loading container非表示
	loadingcontainer.visible=false;
	loading=false;//loading表示判定


	//ボタンを作る
	if (clickbtnUse) {set_thumbnalBtn();}

	//画像があれば、最初の画像表示 IN
	if (image_max) {
		setTimeout(function() {

			//遅延progressbar最後の前にcompleteが反応する
			event.target.removeEventListener("progress",progress);
			//progressTicker削除
			createjs.Ticker.removeEventListener('tick',progressbar.tick);
			//progress非表示
			progresscontainer.visible=false;

			//Main-Ticker一時削除
			if(!prologueUse) {
				createjs.Ticker.removeEventListener('tick',tick);
			}

			//現在こちら使用
			text_set("");
			stage.update();

			//プロローグの使用
			if(prologueUse) {
				set_prologue();//プロローグ実行
			} else {
				draw();//画像分割
			}


		},2000);
	}

}

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

	createjs.Ticker.addEventListener('tick',tick);
	//MAINテキストアニメ
	set_mainTextanime();
	//調整
	setTimeout(function() {
		//使用していない
	},prologue_time);

}
//プロローグ終了
function end_prologue() {

	//調整
	setTimeout(function() {

		//ステージキャプチャーエレメント/こちら使用
		var canvas=document.getElementById('mainCanvas');

		//ステージキャプチャー画像を入れる
		keep_mainImage=createImgCanvas(canvasWidth,canvasHeight,canvas);//加工すればOK;
		//画像分割最初はOUT
		once=true;

		//MAINテキス非表示
		maintextcontainer.visible=false;
		//Main-Ticker一時削除
		createjs.Ticker.removeEventListener('tick',tick);

		//ボタンコンテナ表示
		if (clickbtnUse) {
			btncontainer.visible=true;
			stage2.update();
		}

		//画像分割に進む
		draw();
		//

	},prologue_time);

}

//ボタン
function set_thumbnalBtn() {

	//ActiveThumbボタンを作る/#6A5ACD
	//activeBtn=createActiveThumb(0,0,thumbW,thumbH,btnRadius,active_color);//点
	activeBtn=createActiveThumb2(0,0,thumbW,thumbH,btnRadius,active_color);//枠

	//全ボタン幅
	var btnW_all=0;

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

		//番号受け渡し
		var no=i;

		//Canvas画像縮小/サイズを与えると自由な大きさを取れる
		var img=createImgCanvas(thumbW,thumbH,assets[no]);
		myBtn[i]=createThumbShapeBtn(img,0,0,thumbW,thumbH,btnRadius,"#000000",no);

		myBtn[i].cursor="pointer";
		//ボタン間隔
		myBtn[i].x=i*interval_W;
		//ボタン判別用のproperty:idを書き込む、未使用
		myBtn[i].id=i;
		//クリックアクション
		myBtn[i].on("click",handleclick,null,false,i);
		//myBtn addChild
		btncontainer.addChild(myBtn[i]);
	}

	//activeBtnを乗っける
	btncontainer.addChild(activeBtn);

	//ボタン収容幅
	btnW_all=interval_W*(image_max-1);
	//ボタンコンテナを中央に修正1
	var btncont_x=(canvasWidth-btnW_all)/2;
	btncontainer.x=btncont_x;
	btncontainer.y=interval_H;

	//非表示
	btncontainer.visible=false;
	stage2.update();

}

//DRAW、アニメ
function draw() {

	globalflag=false;

	//AUTO文字表示/ボタン有効判定
	if (!btnValidity && timer_use =='use') {
		if (clickbtnUse) {text_set("AUTO");}
	};

	//サムネール表示中ならクリア
	if (thumb) {
		thumbBox.visible=false;
		thumb=false;
	}

	//activeボタン変更
	if (clickbtnUse) {

		//active透明修正/activeBtn使用
		for (var i=0; i < image_max; i++) {
			var target=myBtn[i].getChildAt(1);
			target.alpha=(i == image_no) ? 1:0.5;
		}
		//activeBtn移動
		activeBtn.x=myBtn[image_no].x;
		stage2.update();
	}

	//IN OUTを確率で決定
	inType=true;
	var in_no=Math.floor(Math.random()*2);
	if (in_no == 0) {inType=false;}

	//ステージキャプチャー画像があれば最初の画像はOUT
	if (once) {
		inType=false;
		once=false;
	}

	//画像保存がなければIN
	if (!keep_mainImage) {
		inType=true;
	}

	//INの場合画像result取得
	if (inType) {
		mainImage=assets[image_no];
	} else {
		//OUTの場合画像keep.result取得
		mainImage=keep_mainImage;
	}
	//グラフィックに流し込むにresultで処理のため
	keep_mainImage=assets[image_no];

	//カウントクリア
	kcount=0;

	//分割変更
	if (split_free) {
		var splitNo=Math.floor(Math.random()*splitHs.length);
		//分割値代入
		split_h=splitHs[splitNo];//★縦40以上は注意
		split_v=splitVs[splitNo];
	}

	//スライス寸法データを得る1
	slice_set(canvasWidth,canvasHeight,split_h,split_v);
	//分割合計要素数計算
	split_all=split_h*split_v;

	//画像分割貼り付け
	var srcArr=[];//URL容器
	var k=0;
	for (var i=0; i < split_h; i++) {
		for (var j=0; j < split_v; j++) {

			var sliceCanvas=document.createElement("canvas");
			sliceCanvas.width=chip_W[k];
			sliceCanvas.height=chip_H[k];

			var context=sliceCanvas.getContext("2d");
			//トリミング
			context.drawImage(mainImage,chip_pos_X[k],chip_pos_Y[k],chip_W[k],chip_H[k],0,0,chip_W[k],chip_H[k]);
			//Canvasエレメントを保存
			srcArr[k]=sliceCanvas;

			k++;
		}
	}

	//アニメ条件設定
	//配列クリア
	var delay_st=[];
	var delay_pt=[];
	//rotation受渡変数配列
	var rotate_v=[];
	//動きの分類
	moveType="";

	//標準パターン番号削除未使用
	var patternflag=false;
	//パターン番号未使用
	var pattern_no=0;

	//多目的判定用
	var chgxyflag=Math.floor(Math.random()*5);
	//多目的用2
	var chgflag=Math.floor(Math.random()*3);

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

	//タイプ決定フラグ未使用
	var typeflag=0;

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

	//delayed遅延させる/20%
	var delayed=Math.floor(Math.random()*5);
	//半径、幅の70%で外側配置、半分の時あり
	var radius=Math.floor(canvasWidth*0.7);

	//配置disposition位置番号/加算値
	var disposition_no=Math.floor(Math.random()*8);
	var disposition_X=0;
	var disposition_Y=0;

	//スケール方向番号
	var scale_no = scales[Math.floor(Math.random()*scales.length)];
	var scale_X=0;
	var scale_Y=0;
	//回転データ取得
	var rotate=rotates[Math.floor(Math.random()*rotates.length)];

	//透明度
	var alpha_no=Math.floor(Math.random()*2);
	//速度補正係数
	var spd_v=1;

	//radius半径補正、20% 円形の内部位置になる/強制透過
	if (chgxyflag == 0) {radius *=0.5;alpha_no=0;}

	//回転の場合の食み出し防止、長いので見える、透過させる
	if (split_h == 1 || split_v == 1) {
		if (rotate > 0) {alpha_no=0;}
	}

	//Even算出
	var even_v = 1;
	if (split_v % 2 != 0) {even_v = 0;}

	//Bitmap配置、配置条件設定
	var vx=0,vy=0,angle_v=0;

	var shc=(split_h/2)-0.01;
	var svc=(split_v/2)-0.01;
	var diag_no=0;
	var v_x=0;
	var v_y=0;
	flag3=1;
	var k=0;
	for (var i=0; i < split_h; i++) {
		for (var j=0; j < split_v; j++) {

			//Canvasエレメントを表示のためにBitmapに収納
			chip[k]=new createjs.Bitmap(srcArr[k]);

			chip[k].width=chip_W[k];
			chip[k].height=chip_H[k];

			//中央補正
			chip[k].regX=chip_W[k]/2;
			chip[k].regY=chip_H[k]/2;

			//戻り位置計算
			set_pos_X[k]=chip_pos_X[k]+chip_W[k]/2;
    			set_pos_Y[k]=chip_pos_Y[k]+chip_H[k]/2;

			//移動加算値等の計算
			switch(disposition_no){
				case 0://その場所で
					disposition_X=set_pos_X[k];
					disposition_Y=set_pos_Y[k];
					//スケール補正
					scale_no=0;
					spd_v=0.5;
					//スケール例外その場拡大20%
					if (chgxyflag == 2) {scale_no=4;}
				break;
				case 1://外側に、radius半径補正あり180/Math.PI
					var angle=Math.random()*360;
					disposition_X=Math.cos(angle)*radius+(canvasWidth/2);
					disposition_Y=Math.sin(angle)*radius+(canvasHeight/2);
					spd_v=1.5;
				break;
				case 2://左右に中心から補正
					v_x=(canvasWidth/2+chip_W[k]/2)*chg_v;
					disposition_Y=set_pos_Y[k];
					if (!chgflag && i % 2 != 0) {v_x *=-1;}
					if (chgxyflag < 2) {v_x *=flag3;}
					disposition_X=v_x+canvasWidth/2;
					//回転は見出し補正
					if(rotate > 0) {alpha_no=0;}
				break;
				case 3://上下に中心から補正
					disposition_X=set_pos_X[k];
					v_y=(canvasHeight/2+chip_H[k]/2)*chg_v;
					if (!chgflag && j % 2 != 0) {v_y *=-1;}
					if (chgxyflag < 2) {v_y *=flag3;}
					disposition_Y=v_y+canvasHeight/2;
					//回転は見出し補正
					if(rotate > 0) {alpha_no=0;}
				break;
				case 4://YX内部ランダム位置
					disposition_X=Math.floor(Math.random()*canvasWidth);
					disposition_Y=Math.floor(Math.random()*canvasHeight);
					//スケール補正
					scale_no=0;
					spd_v=1;
				break;
				case 5://中央
					disposition_X=canvasWidth/2;
					disposition_Y=canvasHeight/2;
					if (!chgflag) {disposition_X=set_pos_X[k];}
					//スケール補正
					scale_no=0;
					spd_v=0.8;
				break;
				case 6://YX内部ランダム位置
					disposition_X=Math.floor(Math.random()*canvasWidth);
					disposition_Y=Math.floor(Math.random()*canvasHeight);
					//スケール補正
					scale_no=0;
					spd_v=0.8;
				break;
				default://そのほか
					disposition_X=set_pos_X[k];
					disposition_Y=set_pos_Y[k];
					//スケール補正
					scale_no=0;
					alpha_no=0;
					spd_v=0.8;
			}

			//スケール方向決定
			switch(scale_no){
				case 0:
					scale_X=0;scale_Y=0;
				break;
				case 1:
					scale_X=1;scale_Y=1;
				break;
				case 2:
					scale_X=0;scale_Y=1;
				break;
				case 3:
					scale_X=1;scale_Y=0;
				break;
				case 4:
					scale_X=2;scale_Y=2;alpha_no=0;//スケール例外2倍、負荷が大きい
				break;
				default:
					scale_X=0;scale_Y=0;
			}

			//moveType="y-3d";
			if (moveType == 'y-3d') {
				scale_X=-1;scale_Y=1;
			}

			//rotation値の決定 120度x、逆転有り
			rotate_v[k]=rotate*120*chg_v;
			//回転の変化、回転0以外なら交互逆転する、確率33%
			if (chgflag == 1) {rotate_v[k] *= flag3;}

			//初期の移動
			//IN
			if (inType) {
				mov_pos_X[k]=disposition_X;
				mov_pos_Y[k]=disposition_Y;
				chip[k].x=mov_pos_X[k];
    				chip[k].y=mov_pos_Y[k];
				chip[k].rotation=rotate_v[k];
				chip[k].scaleX=scale_X;
				chip[k].scaleY=scale_Y;
				chip[k].alpha=alpha_no;
			}

			//OUT
			if (!inType) {
				mov_pos_X[k]=disposition_X;
				mov_pos_Y[k]=disposition_Y;
				chip[k].x=set_pos_X[k];
    				chip[k].y=set_pos_Y[k];
				//初期の条件
				chip[k].rotation=0;
				chip[k].scaleX=1;
				chip[k].scaleY=1;
				chip[k].alpha=1;
			}

			//表示リストaddChild、stage.updateはしないこと
			//コンテナに収容
			container.addChild(chip[k]);

			k++;
			flag3 *=-1;
		}
		if (even_v) {flag3 *=-1;}
	}

	//delay_no10 ランダムを減らす30%
	if (delay_no == 10 && chgflag) {delay_no=0;}

	//delayの計算/通常より増やした
	var sh=split_h-1;
	var sv=split_v-1;
	var flag3=1;
	var kk=0;//方向違いカウント
	var kkk=0;//半分でカウントダウン
	var k=0;
	for (var i=0; i < split_h; i++) {
		for (var j=0; j < split_v; j++) {

			//縦方向にカウント
			kk=i*split_v+j;
			kkk=k;
			if (k > (split_all-1)/2) {kkk=Math.abs(split_all-k)-1;}

			if (delay_no == 0) {delay_st[k]=(i+j)*delay_speed;}
			if (delay_no > 0 && delay_no < 5) {delay_st[k]=(i+j+k/split_all/4)*delay_speed;}//滑らか
			if (delay_no == 5) {delay_st[k]=(i+j)/2;delayed=1;}
			if (delay_no == 6) {delay_st[k]=kk*delay_speed;}
			if (delay_no == 7) {delay_st[k]=kkk*delay_speed;}
			if (delay_no == 8) {delay_st[k]=(Math.abs(Math.abs(i-sh/2)-sh)+Math.abs(Math.abs(j-sv/2)-sv))*2*delay_speed;}//円形状外から中心に
			if (delay_no == 9) {delay_st[k]=(Math.abs(i-(sh/2))-Math.abs(j-(sv/2)))*3*delay_speed;}//対角組あわせX状に
			if (delay_no == 10) {delay_st[k]=Math.floor(Math.random()*split_all)/2*delay_speed;}//適当なランダム
			if (delay_no > 10 ) {delay_st[k]=k*2*delay_speed;}

			//分割数が少ない場合早いので、間隔をあける1.5-3
			if (split_all < 16) {delay_st[k] *=2;}

			//delayed遅延
			if (delayed == 1) {
				if (flag3 < 0) {delay_st[k] +=1000;}
			}

			k++;
			flag3 *=-1;

		}
		if (even_v) {flag3 *=-1;}
	}

	//delay反転
	if (chgxyflag > 2) {
		delay_st.reverse();
	}

	//OUTの場合下画像を入れるstage.updateはしないこと
	if (!inType) {
		backImage.image=new createjs.Bitmap(keep_mainImage).image;
	}

	//Easeの変更 IN最後遅くOUT等速
	var ease=createjs.Ease.linear;
	if (inType) {ease=createjs.Ease.cubicOut;}

	//TWEENの実行
	var k=0;
	var params={};
	for (var i=0; i < split_h; i++) {
		for (var j=0; j < split_v; j++) {

			if (inType) {
				params={x:set_pos_X[k],y:set_pos_Y[k],scaleX:1,scaleY:1,rotation:0,alpha:1};
			} else {
				params={x:mov_pos_X[k],y:mov_pos_Y[k],scaleX:scale_X,scaleY:scale_Y,rotation:rotate_v[k],alpha:alpha_no};
			}

			var tw=createjs.Tween.get(chip[k])
			.wait(delay_st[k])
			.call(indexchg)
			.to(params,speed*spd_v,ease)
			.call(finshtween);

			k++;

		}
	}

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

}

//重ね順を一番上にする
function indexchg () {
	container.setChildIndex(this,split_all-1);
	//container.setChildIndex(this,0);
}

//要素ごとのアニメ完了処理
function finshtween () {

	//全て完了
	if(kcount == split_all-1 ){
		finshAll();
	}
	//0からカウント加算
	kcount ++;

}

//アニメ全て完了
function finshAll () {

	//Tween全てが完了してから下画像表示
	if (inType) {
		backImage.image=new createjs.Bitmap(mainImage).image;
		stage.update();
	}
	//コンテナの中を削除
	container.removeAllChildren();
	//removeAllTweens必要なら
	//createjs.Tween.removeAllTweens();
	//クリア
	kcount=0;
	globalflag=true;

	//画像処理に時間がかかるので、少し遅延させる
	setTimeout(function() {

		//Ticker OFF
		createjs.Ticker.removeEventListener('tick',tick);

		//タイマー次ぎ開く
		if (timer_use == 'use') {

			if (clickbtnUse) {text_set("AUTO");}
			set_timer();
		}

	},500);

}

//tick
function tick() {
	stage.update();
}

//スライス要素の位置大きさ決定、保存
function slice_set(bw,bh,slh,slv) {

	//スライス/細分しすぎるとroundでエラーになる場合あり修正
	slice_W=Math.round(bw/slh);//YOKO
	slice_H=Math.round(bh/slv);//TATE
	//とりあえずエラー回避のみ
	slice_Wb=bw-slice_W*(slh-1);
	if(slice_Wb < 1) {slice_Wb=2;}
	slice_Hb=bh-slice_H*(slv-1);
	if(slice_Hb < 1) {slice_Hb=2;}

	var k=0;
	for (var i=0; i < slh; i++) {
		for (var j=0; j < slv; j++) {
			//大きさ保存
			chip_W[k]=slice_W;
			if (i == slh-1) {chip_W[k]=slice_Wb;}
			chip_H[k]=slice_H;
			if (j == slv-1) {chip_H[k]=slice_Hb;}
			//位置保存中央補正前
			chip_pos_X[k]=(slice_W*i);
			chip_pos_Y[k]=(slice_H*j);
			k ++;
		}
	}
}

//次ぎの開く要素を計算
function next_set() {

	//次ぎの番号
	image_no +=1;
	if (image_no > (image_max-1)) {image_no=0;}
	draw();

}

//タイマー
function set_timer() {

	//タイマー再セット
	if (timer_use == 'use') {

		//一旦切ってからセット
		clearTimeout(timerID);
		timerID=setTimeout(next_set,time);
	}

}

//BtnClick
function handleclick (event,no) {
	//アニメ中は機能しない
	if (!globalflag) {return;}

	var hit_no=no;

	//表示中番号なら戻る
	if (hit_no == image_no) {
		return;
	} else {
		//ボタン有効/AUTO文字書き換え
		btnValidity=true;
		viewtext.text="";
		//タイマー強制停止
		clearTimeout(timerID);
		//指定番号の画像表示
		image_no=hit_no;

		//少し遅延させるclickは重要だ
		setTimeout(function() {
			text_set(" No."+(image_no+1));
			draw();
		},300);//200-500

	}
}
//TEXT表示
function text_set (t) {
	if (text_use) {
		viewtext.text=t;
		stage.update();
	}
}

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

//create-Shape背景つきボタン
function createThumbShapeBtn (image,x,y,w,h,r,backcolor,no) {

	//BTNコンテナ、黒back付き
	var btn=new createjs.Container();
	var back=new createjs.Shape();//背景
	//Fill
	back.graphics.beginFill(backcolor).drawRoundRect(x,y,w,h,r);
	var shape=new createjs.Shape();
	//BitmapFill
	shape.graphics.beginBitmapFill(image).drawRoundRect(x,y,w,h,r);
	back.shadow=shadow;
	back.regX=shape.regX=w/2;
	back.regY=shape.regY=h/2;
	btn.addChild(back,shape);
	//active判定用
	var no=no;

	//rollover
	btn.addEventListener("rollover",function (e) {
		shape.alpha=1;
		stage2.update();
	});
	//rollout
	btn.addEventListener("rollout",function (e) {
		if(image_no == no){return false;}//active
		shape.alpha=0.5;
		stage2.update();
	});
	return btn;
}

//注意、Activebtn Thumb、赤い枠
function createActiveThumb2 (x,y,w,h,r,activec) {

	//BTNコンテナ
	var btn=new createjs.Container();
	btn.x=x;
	btn.y=y;
	btn.name="btntext";
	var s=new createjs.Shape();
	//共通
	s.graphics.ss(2).s(activec).drawRoundRect(x,y,w,h,r);
	btn.regX=w/2;
	btn.regY=h/2;
	btn.addChild(s);
	return btn;
}

//注意、Activebtn Thumb、赤い点
function createActiveThumb (x,y,w,h,r,activec) {

	//BTNコンテナ
	var btn=new createjs.Container();
	btn.x=x;
	btn.y=y;
	btn.name="btntext";
	var s=new createjs.Shape();
	//共通
	s.graphics.s().beginFill(activec).drawCircle(x,y-h/2,3);//円
	//s.graphics.s().beginFill("#FF0000").drawPolyStar(x,y-h/2,5,3,0.0,90);//3角
	btn.addChild(s);
	return btn;
}

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

//変換は配列で返す、未使用
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;
}

//LinearGradientBox
//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
function createLineGradBox (w,h,color1,color2,color3,direction,type) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");

	//LinearGradient
	var gradient;
	if(direction == 'x') {
		gradient=ctx.createLinearGradient(0,h,w,h);
	}
	if(direction == 'y') {
		gradient=ctx.createLinearGradient(w,0,w,h);
	}
	if(direction == 'xy') {
		gradient=ctx.createLinearGradient(0,0,w,h);
	}
	if(type == 2) {
    		gradient.addColorStop(0,color1);
    		gradient.addColorStop(1,color2);
	}
	if(type == 3) {
    		gradient.addColorStop(0,color1);
		gradient.addColorStop(0.5,color2);
    		gradient.addColorStop(1,color3);
	}
	ctx.fillStyle=gradient;
	//FILL
	ctx.fillRect(0,0,w,h);

	return canvas;
}

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

//MAINテキストアニメ/現在使用
function set_mainTextanime() {

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

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

	//ランダム配置のため全幅の計算を先に
	for (var i=0; i < textlen; i++) {
		maintext_W +=textChip[i].width;
		if(i < textlen) {maintext_W +=text_spc;}
	}
	//コンテナ中央ランダムのため速く決めた
	//X
	if (center) {maintextcontainer.x=(canvasWidth-maintext_W)/2;}
	else {maintextcontainer.x=mtcontainer_x;}
	//Y
	maintextcontainer.y=mtcontainer_y;

	//移動
	var delay_st=[];
	//パターン番号
	var pattern_no=Math.floor(Math.random()*6);
	//多目的判定用フラグ
	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 rotate_no=chgflag*chg_v;
	//スケール
	var sclsdata=[1,1,1,.5,4,8];
	var scls=sclsdata[Math.floor(Math.random()*sclsdata.length)];
	//delay番号
	var delay_no=Math.floor(Math.random()*3);

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

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

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

		//全幅計算は上で行っている
		//maintext_W +=textChip[i].width;
		//if(i < textlen) {maintext_W +=text_spc;}

		//移動左右1、X方向のみ
		if (pattern_no == 0) {
			textChip[i].x=canvasWidth*chg_v;
			textChip[i].y=textPosy[i];
		}
		//移動左右2、Y方向ズレ
		if (pattern_no == 1) {
			textChip[i].x=canvasWidth/2*chg_v;
			textChip[i].y +=100*flag*chg_v*(chgflag2-1);
		}
		//移動上下
		if (pattern_no == 2) {
			textChip[i].x=textPosx[i];//その場
			textChip[i].y=canvasHeight/2*chg_v*(chgflag+1);
			if (chgflag == 1) {
				textChip[i].y *=flag;//上下交互
			}
		}
		//ランダム
		if (pattern_no == 3) {
			//globalToLocal
			var point=maintextcontainer.globalToLocal(Math.random()*canvasWidth,Math.random()*canvasHeight);
			textChip[i].x=point.x;
			textChip[i].y=point.y;
		}
		//文字列の中心から
		if (pattern_no == 4) {
			textChip[i].x=maintext_W/2;
			textChip[i].y=textPosy[i];//その場
		}
		//その場所から
		if (pattern_no == 5) {
			textChip[i].x=textPosx[i]+20*(chgflag-1);//その場少しずらす
			textChip[i].y=textPosy[i];//その場
		}

		textChip[i].rotation=rotate_no*180*(chgflag2-1);
		textChip[i].alpha=0;
		textChip[i].scaleX=scls;
		textChip[i].scaleY=scls;

		//delay
		delay_st[i]=100*i;//標準
		if (delay_no == 1) {delay_st[i]=20*i*i;}
		if (delay_no > 1) {delay_st[i]=Math.abs(i-sh/2)*150;}//150-200

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

		k ++;
		flag *=-1;
	}
	//delay逆転
	if (chgflag == 0) {
		delay_st.reverse();
	}

	//Tween
	for (var i=0; i < textlen; i++) {
		//Tween
		var twn=createjs.Tween.get(textChip[i])
		.wait(delay_st[i])
		.to({x:textPosx[i],y:textPosy[i],scaleX:1,scaleY:1,alpha:1,rotation:0},1000)
		.wait(100).to({scaleX:2,scaleY:2},50)
		.wait(100).to({scaleX:1,scaleY:1},200)
		.wait(500).call(textshadow);
		//Tween終了
		if(i == textlen-1) {
			twn.wait(2000).call(finshmove);
		}
	}

}

//TEXT陰影処理
function textshadow() {
	//this.shadow=new createjs.Shadow("#000000",0,0,5);//黒
	this.shadow=new createjs.Shadow("#FFFFFF",-1,-1,2);//白ハイライト
}
//finsh終了
function finshmove() {
	//プロローグ終了に進む
	end_prologue();
}

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

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

//簡単なLOADING
function loadingIndicator3 () {

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

	//描画データ
	var alpha_v=1;//透明度
	var alphaback;

	var cx,cy;
	var numNeedles=12;
	var innerR=15;
	var outerR=10;
	var cAngle=-Math.PI/2;
	var nAngle;

	//ライン描画
	nAngle=Math.PI*2/numNeedles;
	for (var i=0; i < numNeedles; i++){

		//回転補正
		rotateflag=cAngle -=nAngle;
		//透明度を描画毎に変更
		if (i > 0) {alpha_v -=0.05;}

		//#CCCCCC
		alphaback=createjs.Graphics.getRGB(204,204,204,alpha_v);
		cx=Math.cos(cAngle)*innerR;
		cy=Math.sin(cAngle)*innerR;
		graphics.beginStroke(alphaback).moveTo(cx,cy);
		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		graphics.lineTo(cx,cy);

	}
	//Shapeに格納
	var s=new createjs.Shape(graphics);
	return s;
}

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

//START

//Imageオブジェクト先読み
var backgroundimage=new Image();
backgroundimage.src="/main/images/yakei.png";//夜景
//backgroundimage.src="/main/images/welcome_back.jpg";//クロス

backgroundimage.onload=function() {
	init();
}
backgroundimage.onerror=function() {
	//代替画像
	backgroundimage=createLineGradBox(canvasWidth,canvasHeight,"#DD8FAB","#910D39","#DD8FAB","y",2);
	init();
}

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


CSS

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


/*日本語 createJS078.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;
}
#btn-box {
width:640px;
height:50px;
margin:10px auto;
padding:0;
}

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

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


簡単な説明


 

CreateJS 画像分割とテキストアニメーションの組み合わせ


従来の toDataURL() を使用しない方式での画像分割とテキストアニメーションの組み合わせです。細部を少々修正していますのでその点を下記に記述します。
それぞれ原型となった記事は下記の通りです。


【参照】当方の記事: CreateJS 画像分割アニメーション、toDataURL変換しない新方式でのテスト

【参照】当方の記事: CreateJS テキストアニメーション ランダム設定のデモ B

 

[説明図]

 

1. 最新の toDataURL() を使用しない方式での画像分割です。
(多少効率化、見た目は以前と変わりありません)
2. プロローグにテキストアニメーションを組み合わせました。
3. 画像分割の最初にアニメーションのテキストをもキャプチャーして画像として分割。
(意外な分割という所ですが、見る人が気がつくかは疑問です)
4. ステージ2を作り、サムネールボタンをつけました。
5. 設定などは、JSの先頭部分をご覧ください。
6. 一応、easeljs-0.7.0 でも作動します。


画像分割数について

Flashなどと比較してCanvas用は処理能力がありませんので、縦横合計分割数50-70位です、横分割の場合でも20-25分割位までを目安にしています。Canvasの大きさ、マシン環境によっても左右されます。 横40分割以上ですと、現時点でエラーが起きることがありますので、少々修正しました、修正部分は下記の通りです。



//スライス要素の位置大きさ決定、保存
function slice_set(bw,bh,slh,slv) {

	//スライス/細分しすぎるとroundでエラーになる場合あり修正
	slice_W=Math.round(bw/slh);//YOKO
	slice_H=Math.round(bh/slv);//TATE
	//とりあえずエラー回避のみ
	slice_Wb=bw-slice_W*(slh-1);
	if(slice_Wb < 1) {slice_Wb=2;}
	slice_Hb=bh-slice_H*(slv-1);
	if(slice_Hb < 1) {slice_Hb=2;}

	var k=0;
	for (var i=0; i < slh; i++) {
		for (var j=0; j < slv; j++) {
			//大きさ保存
			chip_W[k]=slice_W;
			if (i == slh-1) {chip_W[k]=slice_Wb;}
			chip_H[k]=slice_H;
			if (j == slv-1) {chip_H[k]=slice_Hb;}
			//位置保存中央補正前
			chip_pos_X[k]=(slice_W*i);
			chip_pos_Y[k]=(slice_H*j);
			k ++;
		}
	}
}

最後に小さな断片ができますが、余り気づきません。なるべくならばそのようにならない分割数にしてください。
あくまでも少ない分割数での使用を想定した計算になっています。


Tickerの設定

意図的に、必要のない時は Ticker を実行しないように作っています。


プロローグ

テキストアニメーションを実行します。必要のない場合は設定で中止が可能です。


テキストをキャプチャーして画像として分割

新しい試みで、テキストアニメーション実行後の画面(stage)をキャプチャーして画像に変換して画像分割に利用します。最初はOUTにするためにキャプチャー画像を保存します。
実行は一番最初のみですが、下画像とテキストのキャプチャー画像をOUTで分割します。ステージエレメントを drawImage() で画像化しています。最初がINでは当然効果がありません。



//ステージキャプチャーエレメント/こちら使用
var canvas=document.getElementById('mainCanvas');

//ステージキャプチャー画像を入れる
keep_mainImage=createImgCanvas(canvasWidth,canvasHeight,canvas);//加工すればOK;
//画像分割最初はOUT
once=true;

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

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

サムネールボタン

Shape()要素にMatrix処理をしないで、drawImage()で縮小してサムネールを作っています。
ChromeでShape()要素にShadow処理した場合の不具合を解消させるための処置です、ここでの実際は下にShape()要素をおいてそれにShadow処理していますので、無意味ですが改造した場合に効果を発揮できます。
尚、ボタンの角丸処理は、CreateJS Graphicsクラス の通常の drawRoundRect() を使用しています。


1. アニメーション実行中はボタンは機能しませんので、停止中に押してください。
2. サムネールボタンを使用しない場合は、ステージ2のHtmlは必要ありません。
3. ボタンはstage2で処理しています。以前(easeljs-0.6.4)、IE9で stage2 を実行するとエラーがありましたが、現在は大丈夫のようです。


drawImage()で縮小してサムネールを作る点の詳細は下記ページで詳しく説明しています。

【参照】当方の記事: CreateJS Chromeでの shadowフィルター と、Opera での drawRoundRect の不具合の修正


画像、エレメントなどをキャプチャーして画像化

上記の例は、ステージでしたが、そのほか画像、エレメント、コンテナなどをもキャプチャーして画像化してCanvas表示できます。
画像にして、保存することも可能ですが、詳細は次ページで説明します。


使用画像

使用画像は原則、使用者が用意ください。デモでは640x300の大きさを使用しました。



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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧



[1]