POPSブログ

CreateJS 画像分割アニメと、wicks方式サムネールの組み合わせ B

229

  Category:  javascript2013/06/17 pops 

CreateJSを利用して、キャンバスにサムネールをwicks方式で表示します。サムネールを「クリック」すれば「画像分割アニメ」表示します。大変重く成りますので問題が発生し易い様です。画像分割アニメと、wicks方式サムネールのは、stage2 を作ると動かすのに便利ですが不具合が出る確率が大きいので「stage」1つにマトメました。デザインなど従来と少々違いがでます。
easeljs-0.7 でのテストです。

 

CreateJS 画像分割アニメと、wicks方式サムネールの組み合わせB 表示のテスト


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


基本的には、前に作った「画像分割アニメ」と「wicks方式サムネール」ですから、作るには容易いのですが、複数「tick」設定と、複雑な「Twenn」で「IE9」はクラッシュする確率が大きいです。電源を切らねば成りませんので重症です。そのために少々単純化して組み合わせます。stage2、がないので問題は起きません(デモでは起きていません、、)。
前ページそのままでも良いのですが、少し違いを加えました。

 

[説明図]

 

1.「画像分割アニメ」の場合、従来はその都度「tick」(EventListener)を設定していましたが、これはstage全体で1つにしています。よって常時EventListenerが有効になっています。
角丸陰影CSS3設定の関係などのためにサムネール配置位置が違いデザインが少々変更になります。
2.「ボタン」などの配置でstage2を構成すると便利だが、stage2用の「tick」はなるべく設定しない方がよい。
表現が抽象的ですが、設定処理の次第で、「IE9」クラッシュの原因になる可能性がある。
3.「画像分割アニメ」でブラウザによっては、アウトタイプの実行で、下層に挿入する画像を一瞬「一番上に表示」し、Flashingする様な現象がおきる。インタイプでは処理が違うので起きない。
それにも対処するため補正を加えた。(分割画像をBitmap化で toDataURL() 使用の場合)
4. welcome画像(事前に表示する画像、名前は随意)をmanifestリストに登録して読み出しました。最初の分割は IN OUT どちらも可能です(welcome画像の読み出しに失敗すれば、画像は表示しません)。
5. 全体の大きさ、背景色、角丸陰影は CSS3 で設定します。キャンバスの大きさも変更する事。

6. このJSは、分割画像をBitmap化する場合、問題の起きない toDataURL() を使用しない形式に変更しています。但し、ブラウザによっては問題が起きるか不明のため、補正部分はそのままにしています。

 

 

DEMO


CreateJS 画像分割アニメと、wicks方式サムネールの組み合わせ B (createJS020.js)

このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。
/// マシン環境の悪い方は「Chrome」推奨 ///


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/preloadjs-0.4.0.min.js"></script>
<script type="text/javascript" src="js/tweenjs-0.5.0.min.js"></script>

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


HTML (HTML5)


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

別途、メニュー用キャンバス は有りません。また、mainCanvas の高さが大きくなっている事に注意!
キャンバス幅、画像幅は同じにして下さい。


JS

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

一部判定処理を厳密にしているが、基本的に他の画像分割JSと同じです。但し、welcome画像をmanifestリストで読み込んでいます。
注意、位置計算などにはキャンバスの大きさではなく、画像の大きさを使用していますので他のJSと違います。


//日本語
//createJS020.js
//WICKSサムネールデモ用
//easeljs-0.7用

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

//初期設定
var split_free=true;//自動分割 true false
var speed=1000;//拡大移動、アニメ速度
var slide_time;//未使用
var delay_speed=150;//出現間隔、delay基準時間 100-200

//自動分割でない場合の分割
var split_h=11;//標準の横方向分割数、奇数値
var split_v=5;//標準の縦方向分割数、奇数値
var split_all=split_h*split_v;
//自動分割の場合、free分割データを登録/奇数値が良い
var splitHs=[11,11,11,7];
var splitVs=[5,5,5,3];
//スケール方向番号データ 0-3
var scales=[0,0,0,0,1,2,3];
//回転データ、余り回転しない、回転は120度x回転データ
var rotates=[0,0,0,0,1,2,3];

//canvasの大きさ
//全体の大きさは HTML CSS で調整
var chanvasWidth=640;//未使用
var chanvasHeight=300;//未使用

//読み込み画像の大きさ
var imageW=640;
var imageH=300;

//タイマーの使用切り替え可能/use
var timer_use="use";
//タイマー値 5000-10000
var time=8000;

//clickbtnの使用 useのこと
var clickbtn_use="use";
//Loading AUTOの文字を表示するかuse
//タイマーの使用しないときAUTOの文字なし
var text_use="use";

//サムネールの大きさ余白
var thumbW=64;
var thumbH=30;
var margin=2;//余白
var thumbRadius=5;//角丸半径

//wicks全体の幅、高さ、簡略化
var wicks_W=300;
var wicks_H=45;
//サムネール配置間隔/スペース考慮
var wicks_space=70;
//wicks位置中央補正
var wicksBox_X=0;//中央補正します
var wicksBox_Y=10;

//画像manifestリスト
var manifest=[
{src:"/main/images/welcome_back4.jpg",id:"welcome"},
{src:"/main/images/toyota_car10.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car13.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car15.jpg",id:"PHOTO"},
{src:"/main/images/toyota_car16.jpg",id:"PHOTO"}
];

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

//ステージ
var stage;
//Loader
var loader;
//コンテナ
var container;
var backcontainer;
var loadingcontainer;
var progresscontainer;
var btncontainer;

//画像result
var globalflag=false,backImage,mainImage,keep_mainImage,welcomeImage,timerID=null;

//Loading
var loadingShape;
//TEXT
var viewtext;

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

//ボタンが押された/有効
var btnValidity=false;

//読み込み画像result保存容器
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=[];

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

var inType=true;
var moveType="";
var kcount=0;

//ボタン
var myBtn=[];
var activeBtn;
var myThumb=[];

//wicksメニュー構成
var wicksBox;
//wicksホルダー
var wicksfolder;
//position関連変数
var position_st=[];//初期標準位置保存配列
var position_op=[];//オープン位置保存配列
var position_cl=[];//クローズ位置保存配列

//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);
var shadow2=new createjs.Shadow("#FFFFFF",1,1,2);//影2未使用
var shadow3=new createjs.Shadow("#000000",0,0,8);//影3

//最初の画像0のこと
var image_no=0;
//画像数
var image_max=0;

//welcome画像は有るか
welcomeflag=false;
//update
var update=true;


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

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

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

	//welcome画像層 空画像
	welcomeImage=new createjs.Bitmap();
	stage.addChild(welcomeImage);
	//
	stage.update();


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

	//スライス画像層、空コンテナを作る、使いまわし
	container=new createjs.Container();
	//MASK backrect利用
	container.mask=backrect;
	stage.addChild(container);

	//ボタンコンテナ、ボタンはあとで作る
	btncontainer=new createjs.Container();
	//ボタンコンテナをステージにaddChild
	stage.addChild(btncontainer);
	btncontainer.visible=false;
	stage.update();

	//loadingコンテナを作る
	loadingcontainer=new createjs.Container();
	stage.addChild(loadingcontainer);
	//LOADINGを作る
	loadingShape=loadingIndicator();
	loadingShape.x=imageW/2;
	loadingShape.y=imageH/2;
	//tickを設定
	loadingShape.tick=function (){
		if(loading) {
			loadingShape.rotation +=5;
			stage.update();
		}
	}
	//loading addEventListenerを設定
	createjs.Ticker.addEventListener('tick',loadingShape.tick);
	//コンテナに貼り付け
	loadingcontainer.addChild(loadingShape);
	loading=true;//loading表示判定

	stage.update();

	//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);
			stage.update();
		}
	}
	//Ticker.Listener設定
	createjs.Ticker.addEventListener('tick',progressbar.tick);
	//addChild
	progresscontainer.x=imageW/2;
	progresscontainer.y=imageH/2;
	progresscontainer.addChild(progressbar,progtext);
	stage.addChild(progresscontainer);

	//簡易TEXT
	viewtext=new createjs.Text("","12px Arial","#FFFFFF");
	viewtext.x=20;
	viewtext.y=15;
	viewtext.maxWidth=imageW-40;
	viewtext.lineHeight=20;
	viewtext.textBaseline="bottom";
	viewtext.shadow=shadow;//SHADOW処理
	stage.addChild(viewtext);
	set_text("Loading Now!");

	stage.update();

	//Ticker設定
	createjs.Ticker.setFPS(30);
	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 (event) {

	var id=event.item.id;

	//welcome画像
	if (id == 'welcome') {
		welcomeflag=true;
	}
	//画像選別
	if (id == 'PHOTO') {
		//エラー無しの画像をassets容器に保存
		assets.push(event.result);
	}
}
//全ての画像読み込み完了
function complete (event) {

	//画像数確認、再計算
	image_max=assets.length;
	//簡易TEXT
	set_text("Loading End!");
	//loader Listener削除
	loader.removeEventListener("fileload",fileload);
	loader.removeEventListener("complete",complete);

	//loading EventListener削除
	createjs.Ticker.removeEventListener('tick',loadingShape.tick);
	//非表示でも良い
	loadingcontainer.visible=false;
	loading=false;//loading表示判定

	//welcome画像ロード成功ならwelcome表示
	if (welcomeflag) {
		welcomeImage.alpha=0;
		//保存値に代入
		keep_mainImage=new createjs.Bitmap(loader.getResult("welcome")).image;
		//Fade表示
		welcomeImage.image=new createjs.Bitmap(loader.getResult("welcome")).image;
		var tween=createjs.Tween.get(welcomeImage)
		.to({alpha:1},500);
	}

	//画像があれば、最初の画像表示
	if (image_max > 0) {

		//早すぎるので調整
		setTimeout(function() {

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

			//簡易TEXTクリア
			set_text("");
			//viewtext.visible=false;

			//stage.update();
			//Menuを作る
			drawMenu ();

		},1500);
	}
}

//wicksサムネールを作る/wicksホルダーのみの構造
function drawMenu () {

	//ボタン幅、高さ
	var btnW=wicks_space;//サムネール配置間隔
	var btnH=(thumbH+margin*2);

	//部品構成
	wicksBox=new createjs.Container();
	//wicksホルダー/バックRectはマスクで
	wicksfolder=new createjs.Container();
	//ホルダーmask、ホルダー背景色なし
	var wicksmask=new createjs.Shape();
	//色をつけるならbeginFill('#FFFFFF')など
	wicksmask.graphics.beginFill().drawRect(0,0,wicks_W,wicks_H);
	//フォルダーMASK
	wicksfolder.mask=wicksmask;
	//addChild
	wicksBox.addChild(wicksmask,wicksfolder);
	wicksBox.x=wicksBox_X;
	wicksBox.y=wicksBox_Y;

	//addChild btncontainer
	btncontainer.addChild(wicksBox);

	var fldr_W=wicks_W;
	var kankaku=(fldr_W-btnW)/(image_max-1);

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

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

		//配置位置を計算保存、中央補正
		//position保存
		position_st[i]=(fldr_W/image_max*i)+btnW/2;
		position_op[i]=(kankaku*i)+btnW/2;
		position_cl[i]=fldr_W-kankaku*(image_max-i)+btnW/2;
		if(i == 0) {position_cl[0]=btnW/2;position_op[0]=btnW/2;}//1番目補正

		//Bitmap 現在こちら使用
		myThumb[i]=createThumbBox(assets[no],0,0,thumbW,thumbH,thumbRadius,margin,imageW,imageH,no);

		//配置/横均等
		myThumb[i].x=position_st[i];
		//縦は中央に
		myThumb[i].y=wicks_H/2;

		//判別用のproperty:idを書き込む
		myThumb[i].id=i;

		myThumb[i].cursor='pointer';
		//myThumb wicksfolderにaddChild
		wicksfolder.addChild(myThumb[i]);

		//on形式クリックアクション
		myThumb[i].on("click",handleclick,null,false,i);

	}

	//wicks中央
	btncontainer.x=Math.round((imageW-wicks_W)/2);
	btncontainer.y=imageH+wicksBox_Y;
	btncontainer.visible=true;

	//ダミーバックアクション補正
	var dummyback=new createjs.Shape();
	dummyback.graphics.beginFill('#FFFFFF').drawRect(0,0,btnW,wicks_H);
	dummyback.x=wicks_W;

	//rollover-action
	dummyback.addEventListener('rollover',function (e) {
		return false;
	});
	wicksfolder.addChild(dummyback);

	//遅延
	setTimeout(function() {

		//画像表示に進む
		draw();

	},1000);

}

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

	globalflag=false;

	//active変更/tweenしない
	set_open(image_no);

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

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

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

	//最初、変更したので使用していない
	if (once) {
		once=true;
	}

	//keep値が無ければ強制IN
	//keep_mainImage画像result値が無くOUTは分割drawImage()でエラーになるので注意
	if (!keep_mainImage) {inType=true;}

	//INの場合画像result取得
	if (inType) {
		mainImage=assets[image_no];
	} else {
		//OUTの場合画像keep.result取得
		mainImage=keep_mainImage;
	}
	//OUT用result値保存
	keep_mainImage=assets[image_no];

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

	//分割変更
	if (split_free) {
		splitNo=Math.floor(Math.random()*splitHs.length);
		//分割値代入
		split_h=splitHs[splitNo];
		split_v=splitVs[splitNo];
	}

	//分割エラー修正
	if (!split_h) {split_h=1;}
	if (!split_v) {split_v=1;}

	//最初の画像は分割しない
	if (once) {
		//split_h=1;
		//split_v=1;
	}


	//スライス寸法データを得る1
	slice_set(imageW,imageH,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.setAttribute("width",chip_W[k]);
			sliceCanvas.setAttribute("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]);
			//srcArr[k]=sliceCanvas.toDataURL("image/png");
			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(imageW*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++) {

			//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+(imageW/2);
					disposition_Y=Math.sin(angle)*radius+(imageH/2);
					spd_v=1.5;
				break;
				case 2://左右に中心から補正
					v_x=(imageW/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+imageW/2;
					//回転は見出し補正
					if(rotate > 0) {alpha_no=0;}
				break;
				case 3://上下に中心から補正
					disposition_X=set_pos_X[k];
					v_y=(imageH/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+imageH/2;
					//回転は見出し補正
					if(rotate > 0) {alpha_no=0;}
				break;
				case 4://YX内部ランダム位置
					disposition_X=Math.floor(Math.random()*imageW);
					disposition_Y=Math.floor(Math.random()*imageH);
					//スケール補正
					scale_no=0;
					spd_v=1;
				break;
				case 5://中央
					disposition_X=imageW/2;
					disposition_Y=imageH/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()*imageW);
					disposition_Y=Math.floor(Math.random()*imageH);
					//スケール補正
					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();
	}

	//updateを切る
	update=false;

	//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++;

		}
	}

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

}

//重ね順を一番上にする
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();
	//ボタン有効解除
	btnValidity=false;

	//welcome画像層画像を消す
	if (once) {
		welcomeImage.visible=false;
		once=false;
	}

	//flag
	kcount=0;
	globalflag=true;

	//画像処理に時間がかかるので、少し遅延させる
	setTimeout(function() {
		//Ticker OFF
		//createjs.Ticker.removeEventListener('tick',tick);
		//タイマー次ぎ開く
		if (timer_use == 'use') {
			set_timer();
		}
	},500);

}

//スライス要素の位置大きさ決定、保存
function slice_set(bw,bh,slh,slv) {
	//スライス
	slice_W=Math.round(bw/slh);//YOKO
	slice_H=Math.round(bh/slv);//TATE
	slice_Wb=bw-slice_W*(slh-1);
	slice_Hb=bh-slice_H*(slv-1);
	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 ++;
		}
	}
}

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

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

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

}

//タイマー
function set_timer() {

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

//VIEWTEXT
function set_text(t) {
	if (text_use=='use') {
		viewtext.text=t;
	}
}

//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() {
			draw();
		},300);//200-500

	}
}

//menu-open/tweenしない形
function set_open(no) {
	for (var i=0; i < image_max; i++) {
		if (i <= no) {
			myThumb[i].x=position_op[i];
		} else {
			myThumb[i].x=position_cl[i];
		}
	}
}
//reset/tweenしない形
function reset_open() {
	for (var i=0; i < image_max; i++) {
		myThumb[i].x=position_st[i];
	}
}

//slide-tween
function set_slide(no) {
	//
	var x_v;
	for (var i=0; i < image_max; i++) {

		if (i <= no) {
			x_v=position_op[i];
		} else {
			x_v=position_cl[i];
		}
		var tween=createjs.Tween.get(myThumb[i])
		.wait(250)
		.to({x:x_v},200);
		//.call(finshtween2);
	}
}
//tween
function reset_slide() {
	//
	var x_v;
	for (var i=0; i < image_max; i++) {
		x_v=position_st[i];
		var tween=createjs.Tween.get(myThumb[i])
		.to({x:x_v},150);
		//.call(finshtween2);
	}
}
//finshtween2、未使用
function finshtween2() {
	//
}

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

//ThumbBox表示/update自動
function openThumbBox(no) {
	//サムネール画像書き換え/画像result取得
	thumbImage.image=new createjs.Bitmap(assets[no]).image;
	thumbBox.x=thumb_x;//X位置
	thumbBox.alpha=0;
	thumbBox.visible=true;
	thumb=true;
	//stage.update();
}
//ThumbBox非表示
function closeThumbBox(no) {
	//サムネール画像クリア空画像挿入
	//thumbImage.image=new createjs.Bitmap().image;
	thumbBox.visible=false;
	thumb=false;
	//stage.update();
}

//create-box
function createThumbBox (image,x,y,w,h,r,m,imgw,imgh,no) {

	//サムネールBOX
	box=new createjs.Container();
	var thumbimg=new createjs.Bitmap(image);
	thumbimg.x=m;
	thumbimg.y=m;
	//縮小
	thumbimg.scaleX=w/imgw;
	thumbimg.scaleY=h/imgh;
	//back
	var thumbback=new createjs.Shape();
	thumbback.graphics.s(0).beginFill('#FFFFFF');
	operaRoundRect(thumbback,x,y,w+m*2,h+m*2,4);

	thumbback.shadow=shadow;

	box.addChild(thumbback,thumbimg);
	box.regX=(w+m*2)/2;
	box.regY=(h+m*2)/2;

	//rollover
	box.addEventListener('rollover',function (e) {
		//
		set_slide(no);
	});
	//rollout
	box.addEventListener('rollout',function (e) {
		//
		//reset_slide();
	});

	return box;
}

//簡単なLOADING
function loadingIndicator(){

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

	//描画データ
	var cx,cy,
	numNeedles=12,
	innerR=10,
	outerR=5,
	cAngle= -Math.PI/2,
	nAngle;

	//ライン描画
	nAngle=Math.PI*2/numNeedles;
	for (var i=0; i < numNeedles; i++){
		cAngle +=nAngle;
		cx=Math.cos(cAngle)*innerR;
		cy=Math.sin(cAngle)*innerR;
		graphics.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
init();

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


CSS

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


/*日本語 createJS020.css*/

#demo-wrap {
position:relative;
top:0;left:0;
padding:0;
width:auto;
height:380px;
text-align:center;
}

#image-box {
position:relative;
top:0;left:0;
width:640px;
height:380px;
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:#FFFFFF;
}

#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;
}

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


簡単な説明


JS設定のcanvasの高さは実際の値ではない

canvasの大きさ、canvasHeight はJS設定では画像の高さです、実際のHTML CSS ではそれより大きくなっていますので注意下さい。
canvasの大きさは未使用です。計算には画像の大きさを使用していますから、createJS019.jsと違いますので注意。

Canvasの高さなどは HTML CSS で調整下さい。Canvasの幅、画像幅は同じにすること。


//canvasの大きさ
//全体の大きさは HTML CSS で調整
var chanvasWidth=640;//未使用
var chanvasHeight=300;//未使用

//読み込み画像の大きさ
var imageW=640;
var imageH=300;

Tickerの設定は1つです

通常、「画像分割」の場合は、画像分割処理の時に専用のTickerを設定して、「サムネールボタン」などはstage2配置で別のTickerを設定しましたが、処理如何では「IE9」のトラブルになる恐れがあるために、Tickerを1つにしています。


IE9の異常は「無限ループ」に陥った様な症状である。昔から、IEはこの点弱いようだから、処理の複雑さに対処できない面があるのだろう。他のブラウザでは起きない。


stage2をなくしたら、「サムネールボタン」にTween設定にしても異常は起きないようです。但しTweenが複雑な場合はどうなるかは不明。Tweenなしの簡単な形式はより安心です。改造の点を記載しておきます。


Ticker設定位置は随意です。サンプルでは init() の最後に設定しました。


function init() {

	略す

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

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

「サムネールボタン」の軽量簡素化

主の画像処理の負荷が大きいので、「サムネールボタン」などは軽量簡素化しました。「wicks方式サムネール」はスムーツな動きはしませんが Tween を使用して動かしています。
このデモでは、stage2用の「tick」は設定はしていません。拠って、IE9が異常を来たすことは有りません。


1. stage2用の「tick」は設定はしていません。(IE9で異常を来たす事がある)
2. 画像分割に負荷がかかるので、メニューを簡素化した。他では「ボタン」類を画像より分離していることが多かったが、これは全てstage1つに収容しています。
3. サムネールのshadow処理を削除すれば多少スムーツに動く。
4. 出来れば簡素なボタンのほうがモット良い。ボタンなしはモットモット良い。


「サムネール」アクションの簡素化

「サムネール」のアニメは、初期ではTweenする様に作られていますが、次ぎの様にTweenをなくしさらに簡素化も可能です。stage2「tick」を設定していませんので、IE9に影響は有りません。


簡単にする場合の変更箇所、現在表示「サムネール」を開くactive変更は、tweenする場合の設定も可能ですが、負荷など考え簡単な set_open() を使用している。


function draw() {

	略す

	//active変更/tweenしない
	set_open(image_no);
	//tweenする場合
	//set_slide(image_no);

	略す
}

Tweenを使用した場合、現在こちら設定


//slide-tween
function set_slide(no) {
	//
	var x_v;
	for (var i=0; i < image_max; i++) {

		if (i <= no) {
			x_v=position_op[i];
		} else {
			x_v=position_cl[i];
		}
		var tween=createjs.Tween.get(myThumb[i])
		.wait(250)
		.to({x:x_v},200);
		//.call(finshtween2);
	}
}
//tween
function reset_slide() {
	//
	var x_v;
	for (var i=0; i < image_max; i++) {
		x_v=position_st[i];
		var tween=createjs.Tween.get(myThumb[i])
		.to({x:x_v},150);
		//.call(finshtween2);
	}
}

Tweenを使用しない場合は、下記の設定に変更すれば良い。見た目大きな違いは無い。

Tweenをなくしさらに簡素化


//menu-open/tweenしない形
function set_open(no) {
	for (var i=0; i < image_max; i++) {
		if (i <= no) {
			myThumb[i].x=position_op[i];
		} else {
			myThumb[i].x=position_cl[i];
		}
	}
}
//reset/tweenしない形
function reset_open() {
	for (var i=0; i < image_max; i++) {
		myThumb[i].x=position_st[i];
	}
}

サムネール rollover rollout アクション

easeljs-0.7より mouseover mouseout が rollover rollout になりましたので変更します。
新しい、rollover rollout、が古い、mouseover mouseout、と同様です。


サムネール rollover rollout アクションはcreateThumbBox()で作る時に設定されている。rolloutのアクションは使用していない。reset_open()を実行する様に変更すれば。サムネールは均等な位置に戻る。

Tween用


	//rollover
	box.addEventListener('rollover',function (e) {
		//
		set_slide(no);
	});
	//rollout
	box.addEventListener('rollout',function (e) {
		//
		//reset_slide();
	});

Tween用を使用しない形


	//rollover
	box.addEventListener('rollover',function (e) {
		//
		set_open(no);
	});
	//rollout
	box.addEventListener('rollout',function (e) {
		//
		//reset_slide();
	});

easeljs-0.7より「クリックアクション」関連のイベント処理が変更になりましたので修正します。


easeljs-0.7から追加された on 形式を使用しました。リスナーが簡単になります。


//on形式クリックアクション
myThumb[i].on("click",handleclick,null,false,i);

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

//BtnClick
function handleclick (event,no) {

	略す

	var hit_no=no;

	略す
}



下層に挿入する画像が一瞬一番上に表示するのを補正する


分割画像をBitmap化する場合、問題の起きない toDataURL() を使用しない形式に変更しています。


 

「下層に挿入する画像が一瞬一番上に表示するのを補正する」前ページで説明しています。
分割画像をBitmap化する場合toDataURL()使用の場合です。

【参照】当方の記事: CreateJS 画像分割アニメと、wicks方式サムネールの組み合わせ


 

その他

DEMO専用です。使用する事は可能ですが、あくまでもテストですので個人の判断で使用下さい。画像などは各自ご用意下さい。JSの先頭部分をお読み下さい。
テストですので、勿論 間違い含有、予告無くスクリプトなど修正する場合があります、ご了承下さい。


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]