POPSブログ

CreateJS Transition Mask 6角形(hexagon)マスク処理してアニメ表示

260

  Category:  javascript2013/11/16 pops 

複数の6角形(hexagon)マスクで画像エフェクトする Transition Mask です。6角形を組み込むために斜め矢来状に分割しているのが特徴です。 6角形、ダイア形を2種類づつ、計4種内包しています。
easeljs-0.7 でのテストです。

 

CreateJS Transition Mask 6角形(hexagon)マスク処理してアニメ表示のテスト


マスクの分割の形式が違うのみで、コードなどは通常のTransition Maskのものとほぼ同じです。


[説明図]

 

1. 矢来分割で、6角形(hexagon)でマスクエフェクトします。
2. 6角形、ダイア形を2種類づつ、計4種内包しています。
3. ランダムに選定して表示します。
4. ひねりskew処理はしていませんし、以前より比較的単純にしました。

 

DEMO


CreateJS Transition Mask 6角形(hexagon)マスク処理してアニメ表示デモ、(createJS045.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/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="300"></canvas>
	</div>
</div>

JS

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


//日本語
//createJS045.js
//Transition 一括画像ロード矢来分割
//hexagon
//easeljs-0.7用

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

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

//タイマー値 5000-10000
var time=6000;
//最初の画像表示までの遅延時間
var wait_time=3000;//3000-8000

//アニメ速度
var shapemask_speed=1000;//Shapeマスク速度 800-1200
var delay_speed=150;//出現間隔、delay基準時間 100-200

//Autoタイマー true false
var autoUse=true;

//ベース間隔 図形の大きさ 並び数 保存配列
//6角. 6角B. ダイヤ. ダイヤ角丸
var boxW=[130,76,100,100];//ベース
var boxH=[76,130,100,100];
var partsW=[88,88,102,100];//図形の大きさ
var partsH=[88,88,102,100];
var splitH=[11,18,14,14];//並び数
var splitV=[5,3,4,4];

//保存データを使用する、原則こちら使用
var dataUse=true;//true false

//保存データをランダム表示、dataUse=trueで有効
//ランダムでない場合は指定図形番号を表示
var randomUse=true;

//自動分割の使用
var autoSplit=true;//true false

//----------------------------------------
//保存データを使用しない場合、任意に決める
//分割数
var maskSplit_h=11;
var maskSplit_v=5;
var maskSplit_all=maskSplit_h*maskSplit_v;
//ベース間隔 6角
var boxWidth=130;
//var boxHeight=76;
var boxHeight=Math.ceil(boxWidth/1.732);
//図形の大きさ
var partsWidth=88;
var partsHeight=88;
//指定図形番号 0-3
var dataNo=0;
//----------------------------------------

//マスクスケール方向番号データ 0-3の値
var maskScales=[0,0,0,0,1,2,3];
//マスク回転データ、回転は120度x回転データ
var maskRotates=[0,0,0,1,1,2,2,3];

//TEXTの使用 true false
var textUse=true;

//画像manifestリスト
var manifest=[
{src:"/main/images/flower01.jpg",id:"PHOTO"},
{src:"/main/images/flower02.jpg",id:"PHOTO"},
{src:"/main/images/flower03.jpg",id:"PHOTO"},
{src:"/main/images/flower04.jpg",id:"PHOTO"},
{src:"/main/images/flower05.jpg",id:"PHOTO"},
{src:"/main/images/flower06.jpg",id:"PHOTO"}
];

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

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

//ステージ
var stage;
//コンテナ
var welcomecontainer;
var backcontainer;
var container;
//Loader
var loader;

//画像result
var globalflag=false,topImage,backImage,mainImage,keep_mainImage,welcomeImage,timerID=null;
//画像保存
var keep_mainImage,errorImage;
//マスクBOX
var maskbox;
var overImage;
//Loading
var loadingShape;
//変数
//loading変数
var loading=false;
//ProgressBar
var progressbar;
var progtext;
var bar_v=0;
//TEXT
var viewtext;

//読み込み画像URL保存容器
var assets=[];

//マスク分割大きさ位置保存容器
var maskChip_W=[],maskChip_H=[],maskChip_pos_X=[],maskChip_pos_Y=[];
//実際配置位置
var set_maskpos_X=[],set_maskpos_Y=[];
//移動配置位置
var mov_maskpos_X=[],mov_maskpos_Y=[];
//マスクスライスObject容器
var maskChip=[];
var maskkcount=0;

//MASK-IMAGE
var img_st=[];
var maskalpha=false;
//変数
var inType=true;

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

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

//ステージ周りセット
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);
	stage.update();

	//welcome画像層画像表示
	welcomecontainer=new createjs.Container();
	stage.addChild(welcomecontainer);
	stage.update();
	
	//Canvas要素保存/幅、高さ、色
	keep_mainImage=createColorCanvas (canvasWidth,canvasHeight,"#000000");

	//下画像層、空画像コンテナを作る
	backcontainer=new createjs.Container();
	backImage=new createjs.Bitmap();
	backcontainer.addChild(backImage);
	stage.addChild(backcontainer);
	
	//上画像層のみ作る
	container=new createjs.Container();
	//コンテナ00
	container.x=0;
	container.y=0;
	stage.addChild(container);

	//loadingコンテナを作る
	loadingcontainer=new createjs.Container();
	stage.addChild(loadingcontainer);
	//LOADINGを作る
	loadingShape=loadingIndicator();
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/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("#FF0000");
			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=canvasWidth/2;
	progresscontainer.y=canvasHeight/2;
	progresscontainer.addChild(progressbar,progtext);
	stage.addChild(progresscontainer);

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

	set_text("START");
	//bulk-load、画像一括ロードに進む
	bulkload();
}

//progressBar
function progress(event) {

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

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

	set_text("Loading Now!");

	//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) {

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

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

	set_text("Loaded!");

	//画像数確認、再計算
	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表示判定

	stage.update();

	//画像があれば、最初の画像表示
	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();
			//画像表示に進む
			draw_image();

		},wait_time);
	}
}

//アニメ分岐
function draw_image() {

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

	//TEXT/AUTO
	set_text("IMAGE "+(image_no+1));

	//keep値が無ければ強制IN
	if (!keep_mainImage) {inType=true;}

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

	keep_mainImage=assets[image_no];
	
	//処理に進む
	shapemask_anime();

}

//マスクshapemaskアニメ
function shapemask_anime() {

	globalflag=false;//未使用
	//カウントクリア
	maskkcount=0;
	var splitNo=0;
	splitNo=dataNo;

	//保存データを使用する
	if(dataUse) {

		//ランダム
		if (randomUse) {dataNo=Math.floor(Math.random()*boxW.length)}
		splitNo=dataNo;//番号

		//データ参照
		boxWidth=boxW[splitNo];
		boxHeight=boxH[splitNo];
		partsWidth=partsW[splitNo];
		partsHeight=partsH[splitNo];

		//分割データ参照
		if (!autoSplit) {
			maskSplit_h=splitH[splitNo];
			maskSplit_v=splitV[splitNo];
		}
	}

	//自動分割値計算
	if (autoSplit) {
		//横
		maskSplit_h=Math.ceil((canvasWidth+boxWidth/2)/(boxWidth/2));
		//縦
		maskSplit_v=Math.ceil((canvasHeight+boxHeight/2)/boxHeight);
	}

	//分割合計要素数計算
	maskSplit_all=maskSplit_h*maskSplit_v;

	//マスクChip
	maskChip=[];
	//MASK-IMAGE
	img_st=[];
	//カスタムマスクChip
	var customChip=false;
	//カスタムマスク拡大率
	var rate_v=1;

	//マスク要素を作る
	var addWidth=boxWidth/2;
	var addHeight=boxHeight/2;
	var add_v=0;
	var add_h=0;

	var k=0;
	for (var i=0; i < maskSplit_h; i++) {
		for (var j=0; j < maskSplit_v; j++) {

			//shape
			maskChip[k]=new createjs.Shape();
			maskChip_W[k]=boxWidth;
			maskChip_H[k]=boxHeight;
			maskChip[k].id=k;
			maskChip[k].regX=0;
			maskChip[k].regY=0;

			//横偶数は原点0、奇数の場合下げる
			if (i % 2 == 0) {add_h=0;} else {add_h=boxHeight/2;}
			//if (i % 2 != 0) {add_h=0;} else {add_h=boxHeight/2;}

			//戻り位置計算
			set_maskpos_X[k]=i*boxWidth/2;
			set_maskpos_Y[k]=j*boxHeight+add_h;

			//hexagon 6角A
			if (splitNo == 0) {
				maskChip[k].graphics.beginFill().drawPolyStar(0,0,partsWidth/2,6,0,0);
				rate_v=1;//拡大率
				customChip=true;
			}
			//hexagon 6角B
			if (splitNo == 1) {
				maskChip[k].graphics.beginFill().drawPolyStar(0,0,partsWidth/2,6,0,-90);
				rate_v=1;//拡大率
				customChip=true;
			}
			//ダイヤ
			if (splitNo == 2) {
				maskChip[k].graphics.beginFill().drawPolyStar(0,0,partsWidth/2,4,0,0);
				rate_v=1;//拡大率
				customChip=true;
			}
			//ダイヤ角丸
			if (splitNo == 3) {
				maskChip[k].graphics.beginFill();
				roundDia(maskChip[k],partsWidth/2,partsHeight/2);
				rate_v=1.1;//拡大率
				customChip=true;
			}

			k++;

		}

	}

	//アニメ条件設定
	//配列クリア
	var delay_st=[];
	var delay_pt=[];
	//rotation受渡変数配列
	var rotate_v=[];

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

	//delay番号
	var delay_no=Math.floor(Math.random()*4);
	//delayed遅延させる/20%
	var delayed=Math.floor(Math.random()*5);

	//透明度
	var alpha_no=Math.floor(Math.random()*2);

	//配置disposition位置
	var disposition_no=Math.floor(Math.random()*7);
	var disposition_X=0;
	var disposition_Y=0;

	//スケール方向番号
	var scale_no = maskScales[Math.floor(Math.random()*maskScales.length)];
	var scale_X=0;
	var scale_Y=0;

	//回転データ取得
	var rotate=maskRotates[Math.floor(Math.random()*maskRotates.length)];

	//半径、幅の70%で外側配置に使用
	var radius=Math.floor(canvasWidth*0.7);
	//radius半径補正、20% 円形の内部位置になる
	if (chgxyflag == 0) {radius *=0.5;}

	//配置条件設定
	var flag3=1;
	var v_x;
	var v_y;
	var k=0;
	for (var i=0; i < maskSplit_h; i++) {
		for (var j=0; j < maskSplit_v; j++) {

			flag3 =1;
			if (i % 2 != 0) {flag3 =-1;}

			//移動加算値等の計算
			switch(disposition_no){
				case 0://その場所で
					disposition_X=set_maskpos_X[k];
					disposition_Y=set_maskpos_Y[k];
				break;
				case 1://外側に、radius半径
					var angle=Math.random()*360;
					disposition_X=Math.cos(angle)*radius+(canvasWidth/2);
					disposition_Y=Math.sin(angle)*radius+(canvasHeight/2);
				break;
				case 2://YX内部ランダム位置
					disposition_X=Math.floor(Math.random()*canvasWidth);
					disposition_Y=Math.floor(Math.random()*canvasHeight);
				break;
				case 3://中央
					disposition_X=canvasWidth/2;
					disposition_Y=canvasHeight/2;
					if (!chgflag) {disposition_X=set_maskpos_X[k];}
				break;
				case 4://少しずらす/ずれない時もある
					disposition_X=set_maskpos_X[k]+partsW[splitNo]/2*(chgflag2-1);
					disposition_Y=set_maskpos_Y[k]+partsH[splitNo]/2*(chgflag4-1);
				break;
				case 5://縦横中央
					disposition_X=set_maskpos_X[k];
					disposition_Y=canvasHeight/2;
				break;
				case 6://縦中央付近
					if (set_maskpos_X[k] >= canvasWidth/2){disposition_X=canvasWidth/2+(chgflag2-1)*100;}
					if (set_maskpos_X[k] < canvasWidth/2){disposition_X=canvasWidth/2+(chgflag4-1)*100;}
					disposition_Y=set_maskpos_Y[k];
					alpha_no=0;
				break;
				default://そのほか
					disposition_X=set_maskpos_X[k];
					disposition_Y=set_maskpos_Y[k];
					//スケール補正
					scale_no=0;
			}

			//スケール方向
			switch(scale_no){
				case 0:
					scale_X=0;scale_Y=0;
				break;
				case 1:
					scale_X=1;scale_Y=1;
					alpha_no=0;
				break;
				case 2:
					scale_X=0;scale_Y=1;
				break;
				case 3:
					scale_X=1;scale_Y=0;
				break;
				default:
					scale_X=0;scale_Y=0;
			}

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

			//カスタムマスクChip拡大補正
			var outscale_X=1;
			var outscale_Y=1;
			//拡大率rate設定
			if (customChip) {outscale_X=rate_v;outscale_Y=rate_v;}

			//初期の移動
			//IN
			if (inType) {
				mov_maskpos_X[k]=disposition_X;
				mov_maskpos_Y[k]=disposition_Y;
				maskChip[k].x=mov_maskpos_X[k];
    				maskChip[k].y=mov_maskpos_Y[k];
				maskChip[k].rotation=rotate_v[k];
				maskChip[k].scaleX=scale_X;
				maskChip[k].scaleY=scale_Y;
				maskChip[k].alpha=1;//1
			}

			//OUT
			if (!inType) {
				mov_maskpos_X[k]=disposition_X;
				mov_maskpos_Y[k]=disposition_Y;
				maskChip[k].x=set_maskpos_X[k];
    				maskChip[k].y=set_maskpos_Y[k];
				//初期の条件
				maskChip[k].rotation=0;
				maskChip[k].scaleX=outscale_X;//カスタム補正
				maskChip[k].scaleY=outscale_Y;
				maskChip[k].alpha=1;//1
			}

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

			k++;
		}

	}

	//delayの計算
	var sh=maskSplit_h-1;
	var sv=maskSplit_v-1;

	var flag3=1;
	var kk=0;//方向違いカウント
	var kkk=0;//半分でカウントダウン
	var k=0;
	for (var i=0; i < maskSplit_h; i++) {
		for (var j=0; j < maskSplit_v; j++) {

			flag3 =1;
			if (i % 2 != 0) {flag3 =-1;}

			//縦方向にカウント
			kk=i*maskSplit_v+j;
			kkk=k;

			if (delay_no == 0) {delay_st[k]=(i+j)*delay_speed;}
			if (delay_no == 1) {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 == 2) {delay_st[k]=Math.floor(Math.random()*maskSplit_all)/2*delay_speed;}//適当なランダム
			//追加、対角中より外に/対角方向違い
			if (delay_no > 2) {delay_st[k]=Math.abs(j*maskSplit_h/maskSplit_v-Math.abs(i-sh)*chg_v)*1.5*delay_speed;}

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

			k++;

		}
	}

	//画像配置
	var k=0;
	for (var i=0; i < maskSplit_h; i++) {
		for (var j=0; j < maskSplit_v; j++) {

			//画像配置とマスク
			img_st[k]=new createjs.Bitmap(mainImage);
			img_st[k].mask=maskChip[k];
			if (inType) {img_st[k].alpha=alpha_no;}
			if (!inType) {img_st[k].alpha=1;}
			container.addChild(img_st[k]);
			k++;
		}
	}

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

	//maskの透明度を変えるか50%
	maskalpha=false;
	if (alpha_no == 0) {maskalpha=true;}

	//テキストを表示
	//set_text("分割[ "+maskSplit_h+"x"+maskSplit_v+": "+maskSplit_all+" ]/ No."+splitNo);

	//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 < maskSplit_h; i++) {

		for (var j=0; j < maskSplit_v; j++) {

			if (inType) {
				params={x:set_maskpos_X[k],y:set_maskpos_Y[k],scaleX:outscale_X,scaleY:outscale_X,rotation:0};
				img_st[k].alpha=alpha_no;
			}
			if (!inType) {
				params={x:mov_maskpos_X[k],y:mov_maskpos_Y[k],scaleX:scale_X,scaleY:scale_Y,rotation:rotate_v[k]};
				img_st[k].alpha=1;
			}

			var tween=createjs.Tween.get(maskChip[k])
			.wait(delay_st[k])
			.call(alphachg)
			.to(params,shapemask_speed,ease)
			.call(finshMasktween);

			k++;

		}
	}

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

}

//マスクスライスalphaTween
function alphachg (event) {
	if (!maskalpha) {return}
	var twn=createjs.Tween.get(img_st[this.id]);
		if (inType) {
			twn.to({alpha:1},shapemask_speed);
		}
		if (!inType) {
			twn.to({alpha:0},shapemask_speed);
		}
}

//マスク個別のアニメ完了
function finshMasktween () {

	//全て完了
	if(maskkcount == maskSplit_all-1) {
		//画像alpha処理調整 200-500
		setTimeout(function(){
			finshAll();
		},600);
	}
	//0からカウント加算
	maskkcount ++;
}

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

	//Tween全てが完了してから下画像表示
	if (inType) {
		backImage.image=new createjs.Bitmap(mainImage).image;
		stage.update();
	}

	set_text("END");

	//removeAllTweens必要なら
	createjs.Tween.removeAllTweens();
	//上画像コンテナの中を削除
	container.removeAllChildren();

	//クリア
	maskkcount=0;

	//画像処理に時間がかかるので、少し遅延させる、あったほうが良い
	setTimeout(function(){

		//Ticker削除
		createjs.Ticker.removeEventListener('tick',tick);

		//AUTO
		if (autoUse) {
			set_text("AUTO");
			set_timer();
		}

	},500);

}

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

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

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

}

//タイマー
function set_timer() {

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

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

//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);
}
//簡易角丸ダイア
function roundDia(s,w,h) {
	s.graphics.moveTo(w*0.2,-h*0.8)
	.lineTo(w*0.8,-h*0.2)
	.quadraticCurveTo(w*1.05,0,w*0.8,h*0.2)
	.lineTo(w*0.2,h*0.8)
	.quadraticCurveTo(0,h*1.05,-w*0.2,h*0.8)
	.lineTo(-w*0.8,h*0.2)
	.quadraticCurveTo(-w*1.05,0,-w*0.8,-h*0.2)
	.lineTo(-w*0.2,-h*0.8)
	.quadraticCurveTo(0,-h*1.05,w*0.2,-h*0.8);
}
//------------------------------------------------------------------------------

//色付きcanvasを作る
function createColorCanvas (w,h,c) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);
	return canvas;
}

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

//簡単な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

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


/*日本語 createJS045.css*/

#demo-wrap {
text-align:center;
}

#image-box {
position:relative;
top:0;left:0;
width:640px;
height:300px;
margin:0 auto;
padding:0;
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;
}
canvas {
border-style:none;
background-color:transparent;
}

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

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


簡単な説明


6角形マスク


 

画像分割及び通常のマスクアニメ処理と同じです

図の様に、配置する場合にずらしてマスクを合わせますが、そのための影響もあります。


1. 通常の分割と比較してズレているために「遅延パターン」のズレが有ります。
(遅延させて表示のパターンを変えているために僅か影響の出るものもある、中心が下方になりやすい)
2. 角形の分割より、合計数が多くなるためマスク要素の大きさが大きくなります。(マスク要素を小さくすることは可能ですが、マシン環境が悪いと動作が重く成ります)
よって、標準の6角形の使用をお勧めします。
3. 使用出来る要素の形はある程度限定されます。(左右上下に対象形が主になります)
4. 現在のマシン性能などの状況を踏まえてのマスクの大きさです。まだ大きめなのが難点になります。
5. 今後、マシン性能など環境が良くなれば、自由度は増します。


分割寸法などの変更

配置位置は三角関数で計算すれば算出できますが、マスクを小さくすると分割合計数が大きくなり、急激に重く成りますので動作環境を考慮ください。90度回転させた6角形は少々分割合計数が大きくなります。
マスクをピッタリと合わせたい場合に、寸法にマチガイが無くとも薄い隙間が発生しますので、マスクの大きさを微調整します。重なりが有るとエフェクト時キレイに見える場合もあります。

重なりなどは、マスク要素を拡大して調整も出来ますが、このデモではマスク要素の寸法を微調整してあわせました。


データを登録します

//ベース間隔 図形の大きさ 並び数 保存配列
//6角. 6角B. ダイヤ. ダイヤ角丸
var boxW=[130,76,100,100];//ベース
var boxH=[76,130,100,100];
var partsW=[88,88,102,100];//図形の大きさ
var partsH=[88,88,102,100];
var splitH=[11,18,14,14];//並び数
var splitV=[5,3,4,4];

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

拡大率で重なりの調整は可能です、customChipは未処理です

//hexagon 6角A
if (splitNo == 0) {
	maskChip[k].graphics.beginFill().drawPolyStar(0,0,partsWidth/2,6,0,0);
	rate_v=1;//拡大率
	customChip=true;
}

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

-90度回転させた形、drawPolyStar()で-90設定しました

//hexagon 6角B
if (splitNo == 1) {
	maskChip[k].graphics.beginFill().drawPolyStar(0,0,partsWidth/2,6,0,-90);
	rate_v=1;//拡大率
	customChip=true;
}

角丸のダイア形

ダイア形を角丸にしていますので、マスクで四隅にマスク漏れが出ますから拡大補正しています。
色々な形を作るのは大変ですので余り6角形以外の図形を描く方はそうはいないと思います。


//ダイヤ角丸
if (splitNo == 3) {
	maskChip[k].graphics.beginFill();
	roundDia(maskChip[k],partsWidth/2,partsHeight/2);
	rate_v=1.1;//拡大率
	customChip=true;
}

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

//簡易角丸ダイア
function roundDia(s,w,h) {
	s.graphics.moveTo(w*0.2,-h*0.8)
	.lineTo(w*0.8,-h*0.2)
	.quadraticCurveTo(w*1.05,0,w*0.8,h*0.2)
	.lineTo(w*0.2,h*0.8)
	.quadraticCurveTo(0,h*1.05,-w*0.2,h*0.8)
	.lineTo(-w*0.8,h*0.2)
	.quadraticCurveTo(-w*1.05,0,-w*0.8,-h*0.2)
	.lineTo(-w*0.2,-h*0.8)
	.quadraticCurveTo(0,-h*1.05,w*0.2,-h*0.8);
}

マスク要素を回転させて配置も可能ですが、IN OUT が有るためにその辺を書き直さなければならない繁雑さがあるので、簡単に専用で描画した。


マスク要素全体の移動

上図の様に、画像とマスクの配置がキレイに合うわけでは有りませんので合わせる為に全体の移動は可能です。 コンテナを移動しても、画像共に動くので意味は有りませんがマスク位置に「移動量」を加算すればずれます。実際に実行する事はないと思いますが、参考に記載する。(デモでは行っていません)


戻り位置計算でマスク要素の各原点を決定している

//戻り位置計算
set_maskpos_X[k]=i*boxWidth/2;
set_maskpos_Y[k]=j*boxHeight+add_h;

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

XY方向の移動量を加算すれば良い、反対方向ならマイナス値を加算

set_maskpos_X[k]=i*boxWidth/2+移動量;
set_maskpos_Y[k]=j*boxHeight+add_h+移動量;

交互遅延

以前は「交互遅延」により互い違いに「遅延時間」を与えることで「市松状のパターン」を作っていましたが、この「デモ」のJSでは出来ません。(物理的に無理で有り、離れずに連続してしまう)
但し、「ダイア」の場合は配置の関係上、「市松状のパターン」に見えます。

余り効果が無い時もありますが、「遅延時間」を与えています。其れなりの変化はある。


分割値計算

原則的には、縦横の要素の並び数を「計算して登録」しますが、簡易に計算は可能です。但し誤差が出る場合もあるかも知れません。
実際に動作させれば、わかりますのでその場合は「自動分割値計算」を解除して「計算して登録」にして下さい。


計算して登録

var splitH=[11,18,14,14];//並び数
var splitV=[5,3,4,4];

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

//自動分割値計算
if (autoSplit) {
	//横
	maskSplit_h=Math.ceil((canvasWidth+boxWidth/2)/(boxWidth/2));
	//縦
	maskSplit_v=Math.ceil((canvasHeight+boxHeight/2)/boxHeight);
}

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

分割数、などの確認はテキストを表示させれば確認できます

//テキストを表示
//set_text("分割[ "+maskSplit_h+"x"+maskSplit_v+": "+maskSplit_all+" ]/ No."+splitNo);

一応これでいけると思うのですが....


マスク要素を下げる

マスク要素を下げる場合には奇数の列(図参照)を下げたほうが、パターンが少々キレイのようである。


//横偶数は原点0、奇数の場合下げる
if (i % 2 == 0) {add_h=0;} else {add_h=boxHeight/2;}
//if (i % 2 != 0) {add_h=0;} else {add_h=boxHeight/2;}

//戻り位置計算
set_maskpos_X[k]=i*boxWidth/2;
set_maskpos_Y[k]=j*boxHeight+add_h;

 

【参照】当方の記事: CreateJS TransitionMask 画像を複数の分割Shape()でマスク処理してアニメ表示する

【参照】当方の記事: CreateJS Transition Mask 画像を複数のShapeでマスク処理してアニメ表示B



 

画像

画像は各自用意ください。写真画像 640x300サイズ


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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]