複数の形状の違う「画像分割」と「マスク要素」を組み合わせて画像エフェクトする TransitionMask 番外編です。かなり複雑で「重症お病気系エフェクト」ですが、目の錯覚で区別の付かないものも有ります。
easeljs-0.7 でのテストです。
CreateJS 画像分割とTransitionMaskを組み合わせてアニメ表示する、番外編テスト
過度に組み合わせて面倒にしているだけで、見分けすら付かない状態です。(ここで笑う)
やる事がなくなると、平常心を失い色々と暴挙的エフェクトとなるのが常である。アイデアとは程遠い感じです。
TransitionMaskは適当な名前ですし、動けばTransitionでしょうか、単なるエフェクトか?ドウでも良いことです!
[説明図]

DEMO
CreateJS 画像分割とTransitionMaskを組み合わせてアニメ表示する、番外編デモ、(createJS048.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
createJS048.js、JS名は任意に変更可。注意、easeljs-0.7用です。
//日本語
//createJS048.js
//画像分割マスク分割組 一括画像ロード
//easeljs-0.7用
//------------------------------------------------------------------------------
//初期設定
//原則こちらをtrueで実行する
var split_free=true;//自動分割 true false
var speed=1000;//800-1200 拡大移動、アニメ速度
var shapemask_speed=1000;//マスク速度 800-1200
var delay_speed=150;//出現間隔、delay基準時間 100-200
//自動分割でない場合の分割
//分割データ0番として処理されます
var split_h=11;//標準の横方向分割数、奇数値
var split_v=5;//標準の縦方向分割数、奇数値
var split_all=split_h*split_v;
//canvasの大きさ/全てこの値を使用
var canvasWidth=640;
var canvasHeight=300;
//タイマーの使用、useであること
var timer_use="use";
//タイマー値 5000-10000
var time=6000;
//TEXTの使用 true false
var textUse=true;
//自動分割の場合、free分割データを登録/奇数値が良い
var splitHs=[11,11,10,7,5,11,11,2,2,1,1];
var splitVs=[5,5,6,3,3,2,1,2,4,9,1];
//スケール方向番号データ 0-3
var scales=[0,0,0,0,1,2,3];
//回転データ、余り回転しない、回転は120度x回転データ
var rotates=[0,0,0,0,1,2,3];
//MODE登録
var mode_name=["slice","slice","mask"];
//画像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"}
];
//------------------------------------------------------
//ステージ
var stage;
//コンテナ
var welcomecontainer;
var container;
var backcontainer;
var loadingcontainer;
//ローダー
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;
//welcome画像読み込み判定
var welcomeflag=false;
var welcome_result;
var once=true;
//loading変数
var loading=false;
//最初の画像0のこと
var image_no=0;
//画像数
var image_max;
//shadowフィルター
var shadow=new createjs.Shadow("#000000",0,0,4);
var mode="slice";
var img_st=[];
var maskalpha=false;
var keep_speed=speed;
//------------------------------------------------------------------------------
//ステージ周りセット
function init() {
//STAGE
stage=new createjs.Stage('mainCanvas');
//バックRect/最下位色背景層、無くとも良い
var backrect=new createjs.Shape();
backrect.graphics.beginFill("#FFFFFF").drawRect(0,0,canvasWidth,canvasHeight);
stage.addChild(backrect);
//welcome画像層画像表示
welcomecontainer=new createjs.Container();
//welcome画像挿入
if (welcomeflag) {
welcomeImage=new createjs.Bitmap(welcome_result);
} else {
welcome_result=createColorCanvas (canvasWidth,canvasHeight,"#FFFFFF");
welcomeImage=new createjs.Bitmap(welcome_result);
}
welcomecontainer.addChild(welcomeImage);
stage.addChild(welcomecontainer);
stage.update();
//welcome画像保存
keep_mainImage=welcome_result;
//下画像層、空画像コンテナを作る/寸法設定なくともOK
backcontainer=new createjs.Container();
backImage=new createjs.Bitmap();
backcontainer.addChild(backImage);
stage.addChild(backcontainer);
//スライス画像層、空コンテナを作る、使いまわし
container=new createjs.Container();
stage.addChild(container);
//簡易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);
text_set("START");
//loadingコンテナをステージにaddChild
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();
//画像ロードに進む
bulkload();
}
//bulk-load、画像一括ロード
function bulkload() {
text_set("LOADING NOW");
//Loader
loader=new createjs.LoadQueue(false);
//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表示判定
//画像があれば、最初の画像表示 IN
if (image_max) {
//時間調整
setTimeout(function() {
draw();
},1000);
}
}
//DRAW、アニメ
function draw() {
globalflag=false;
text_set("");
//IN OUTを確率で決定
inType=true;
var in_no=Math.floor(Math.random()*2);
if (in_no == 0) {inType=false;}
//INの場合画像result取得
if (inType) {
mainImage=assets[image_no];
} else {
//OUTの場合画像keep.result取得
mainImage=keep_mainImage;
}
//グラフィックに流し込むにresultで処理のため
keep_mainImage=assets[image_no];
//カウントクリア
kcount=0;
//MODE決定 slice mask
mode=mode_name[Math.floor(Math.random()*mode_name.length)];
maskalpha=false;
rate_v=1;//拡大率
customChip=false;
move_graphics=false;
//多目的用
var maskflag=Math.floor(Math.random()*5);//3以上
var color_mask=false;//カラーマスク
if (maskflag < 2) {color_mask=true;}
//マスク番号
var maskNo=0;
//分割番号
var splitNo=0;
//分割変更
if (split_free) {
splitNo=Math.floor(Math.random()*splitHs.length);
//分割値代入
split_h=splitHs[splitNo];
split_v=splitVs[splitNo];
}
//スライス寸法データを得る1
slice_set(canvasWidth,canvasHeight,split_h,split_v);
//分割合計要素数計算
split_all=split_h*split_v;
//マスクスタイル
var maskStyle=Math.floor(Math.random()*2);
//Even算出
var even_v = 1;
if (split_v % 2 != 0) {even_v = 0;}
//画像分割貼り付け/SliseBitmapクラス
var srcArr=[];//URL容器
var flag3=1;
var k=0;
for (var i=0; i < split_h; i++) {
for (var j=0; j < split_v; j++) {
//Bitmap継承SliseBitmapクラス/Bitmap配列に保存
if (mode == 'slice') {
//SliseBitmap(画像,分割位置X,Y,大きさ横,縦)
chip[k]=new SliseBitmap(mainImage,chip_pos_X[k],chip_pos_Y[k],chip_W[k],chip_H[k]);
color_mask=false;
}
if (mode == 'mask') {
chip[k]=new createjs.Shape();
if(splitNo == 0) {
//楕円
if (maskStyle == 0) {
chip[k].graphics.beginFill().drawEllipse(0,0,chip_W[k],chip_H[k]);//だ円のほうが良い
rate_v=1.5;//拡大率
customChip=true;
move_graphics=false;
color_mask=false;
maskNo=0;
}
//角丸
if (maskStyle > 0) {
chip[k].graphics.beginFill();
operaRoundRect(chip[k],0,0,chip_W[k],chip_H[k],10);//角丸
rate_v=1.1;//拡大率
customChip=true;
move_graphics=false;
color_mask=false;
maskNo=1;
}
}
//通常
if(splitNo > 0) {
//カラーマスク
if (color_mask) {
var color="#FFFFFF";
//1
if (split_all < 2) {color=createjs.Graphics.getHSL(Math.floor(Math.random()*24)/24*360,100,50);}//直接
//2-
if (split_all > 1) {
if (maskflag == 0) {color=createjs.Graphics.getHSL(k/split_all*360,100,50);}//直接
if (maskflag == 1 && flag3 > 0) {color="#000000";}
}
chip[k].graphics.beginFill(color).drawRect(0,0,chip_W[k],chip_H[k]);
}
if (!color_mask) {
chip[k].graphics.beginFill().drawRect(0,0,chip_W[k],chip_H[k]);
color_mask=false;
}
move_graphics=false;
}
}
k++;
flag3 *=-1;
}
if (even_v) {flag3 *=-1;}
}
//アニメ条件設定
//配列クリア
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;
//多目的用4-5
var chgflag3=Math.floor(Math.random()*3);
var chgflag4=Math.floor(Math.random()*3);
//逆転フラグ
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()*14);
//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()*11);
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;}
}
//Bitmap配置、配置条件設定
var vx=0,vy=0,angle_v=0;
//移動係数
var move3_v=(chgflag3-1);
var move4_v=(chgflag4-1);
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++) {
//大きさ
chip[k].width=chip_W[k];
chip[k].height=chip_H[k];
chip[k].id=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];
//補正
if (scale_no == 1) {alpha_no=0;}
spd_v=0.8;
//スケール例外その場拡大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);
if (split_v == 1 && split_all > 1) {scale_no=0;}//食み出し防止
spd_v=1.5;
break;
case 2://左右に中心から補正
v_x=(canvasWidth/2+chip_W[k]/2*rate_v)*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*rate_v;
//回転は見出し補正
if(rotate > 0) {alpha_no=0;}
spd_v=1.2;
break;
case 3://上下に中心から補正
disposition_X=set_pos_X[k];
v_y=(canvasHeight/2+chip_H[k]/2*rate_v)*chg_v;
if (!chgflag && j % 2 != 0) {v_y *=-1;}
if (chgxyflag < 2) {v_y *=flag3;}
disposition_Y=v_y+canvasHeight/2*rate_v;
//回転は見出し補正
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;
case 7://少し移動/移動無しあり
disposition_X=set_pos_X[k]+chip_W[k]/2*move3_v;
disposition_Y=set_pos_Y[k]+chip_H[k]/2*move4_v;
//補正
if (split_all == 1) {rotate=0;}
alpha_no=0;
spd_v=0.8;
break;
case 8://要素の大きさ分移動
disposition_X=set_pos_X[k]+chip_W[k]*move3_v;
disposition_Y=set_pos_Y[k]+chip_H[k]*move4_v;
//補正
if (split_all != 1 && scale_no == 1) {alpha_no=0;}//1枚以外強制
if (move3_v == 0 && move4_v == 0) {alpha_no=0;}//移動無し
if (split_all == 1) {rotate=0;spd_v=1.2;}
break;
case 9://4隅対角
//X
if (i <= shc) {disposition_X=-chip_W[k]/2;}
if (i > shc) {disposition_X=canvasWidth+chip_W[k]/2;}
//Y
if (j <= svc) {disposition_Y=-chip_H[k]/2;}
if (j > svc) {
disposition_Y=canvasHeight+chip_H[k]/2;
if (split_h == 1) {disposition_X=canvasWidth+chip_W[k]/2;}
}
//補正
if (split_v == 1 && i > shc) {
disposition_Y=canvasHeight+chip_H[k]/2;
}
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倍、負荷が大きい
//maskは適用外
if (mode == 'mask') {scale_no=1;scale_X=1;scale_Y=1;alpha_no=0;}
break;
default:
scale_X=0;scale_Y=0;
}
//カラー強制補正
if (color_mask) {alpha_no=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;}
//Mask-alpha
var base_alpha=1;
if (color_mask) {
base_alpha=0;//0
if (inType && scale_no != 1) {
base_alpha=1;
}
}
//初期の移動
//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;
//カラー
if (color_mask) {chip[k].alpha=base_alpha;}//0
}
//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=outscale_X;//カスタム補正
chip[k].scaleY=outscale_Y;
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 == 11) {delay_st[k]=k*1.5*delay_speed;}
//追加、対角中より外に/対角方向違い
if (delay_no > 11) {delay_st[k]=Math.abs(j*split_h/split_v-Math.abs(i-sh)*chg_v)*1.5*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;}
}
//11速度調整
if (delay_no == 11 && split_all > 30) {spd_v=0.8;}
//画像配置
if (mode == 'mask') {
var k=0;
for (var i=0; i < split_h; i++) {
for (var j=0; j < split_v; j++) {
img_st[k]=new createjs.Bitmap(mainImage);
img_st[k].mask=chip[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の透明度を変えるか
maskalpha=false;
if (alpha_no == 0) {maskalpha=true;}
//速度
if (mode == 'mask') {speed=Math.round(keep_speed*spd_v);}
if (mode == 'slice') {speed=shapemask_speed*spd_v;}
//テキストを表示
//text_set("MODE: "+mode+" /分割[ "+split_h+"x"+split_v+": "+split_all+" ] / IN: "+inType+" / splitNo."+splitNo+" / dispositionNo."+disposition_no+" / delayNo."+delay_no+" / colorMask: "+color_mask);
//OUTの場合下画像を入れるstage.updateはしないこと/したに移動
if (!inType) {
//backImage.image=new createjs.Bitmap(keep_mainImage).image;
}
//Easeの変更削除
//TWEENの実行
if (mode == 'slice') {
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 tween=createjs.Tween.get(chip[k])
.wait(delay_st[k])
.call(indexchg)
.to(params,speed)
.call(finshslice_tween);
k++;
}
}
}
//TWEENの実行2
//outのマスクalpha
var out_alpha=1;
if (mode == 'mask') {
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:outscale_X,scaleY:outscale_Y,rotation:0,alpha:1};
}
if (!inType) {
//カラーマスク補正
if (color_mask && scale_no == 1) {out_alpha=0;}
params={x:mov_pos_X[k],y:mov_pos_Y[k],scaleX:scale_X,scaleY:scale_Y,rotation:rotate_v[k],alpha:out_alpha};
}
var tween=createjs.Tween.get(chip[k])
.wait(delay_st[k])
.call(alphachg)
.to(params,speed)
.call(finshmask_tween);
k++;
}
}
}
//OUTの場合下画像を入れる
if (!inType) {
backImage.image=new createjs.Bitmap(keep_mainImage).image;
}
//Firefox
setTimeout(function() {
//Ticker設定
createjs.Ticker.setFPS(20);
createjs.Ticker.addEventListener('tick',tick);
},20);
}
//重ね順を一番上にする
function indexchg () {
container.setChildIndex(this,split_all-1);
//container.setChildIndex(this,0);
}
//スライス個別のアニメ完了
function finshslice_tween () {
//全て完了
if(kcount == split_all-1) {
//画像alpha処理調整
setTimeout(function(){
finshAll();
},200);
}
//0からカウント加算
kcount ++;
}
//マスク個別のアニメ完了
function finshmask_tween () {
//全て完了
if(kcount == split_all-1) {
//画像alpha処理調整
setTimeout(function(){
finshAll();
},speed);
}
//0からカウント加算
kcount ++;
}
//アニメ全て完了
function finshAll () {
//Tween全てが完了してから下画像表示
if (inType) {
backImage.image=new createjs.Bitmap(mainImage).image;
stage.update();
}
//コンテナの中を削除
container.removeAllChildren();
//removeAllTweens バージョン4.2.1
//createjs.Tween.removeAllTweens();
//個別removeTweens
for (var i=0; i < split_all; i++) {
//removeTween
createjs.Tween.removeTweens(chip[i]);
}
kcount=0;
globalflag=true;
//画像処理に時間がかかるので、少し遅延させる
setTimeout(function() {
//Ticker OFF
createjs.Ticker.removeEventListener('tick',tick);
//タイマー次ぎ開く
if (timer_use == 'use') {
set_timer();
}
},500);
}
//tick
function tick() {
stage.update();
}
//スライス要素の位置大きさ決定、保存
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 ++;
}
}
}
//次ぎの開く要素を計算
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);
}
}
//マスクスライスalphaTween
function alphachg (event) {
if (!maskalpha) {return}
var twn=createjs.Tween.get(img_st[this.id]);
if (inType) {
twn.to({alpha:1},speed);
}
if (!inType) {
twn.to({alpha:0},speed);
}
}
//TEXT表示
function text_set (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);
}
//------------------------------------------------------------------------------
//色付き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
}
//------------------------------------------------------------------------------
//Bitmap継承SliseBitmapクラス
(function (window){
function SliseBitmap(img,pos_x,pos_y,c_w,c_h){
//
this.img=img;
this.pos_x=pos_x;
this.pos_y=pos_y;
this.c_w=c_w;
this.c_h=c_h;
//スライス
var slice=document.createElement("canvas");
slice.width=this.c_w;
slice.height=this.c_h;
var context=slice.getContext("2d");
context.drawImage(this.img,this.pos_x,this.pos_y,this.c_w,this.c_h,0,0,this.c_w,this.c_h);
this.initialize(slice);//Canvas要素
}
//Bitmap化
SliseBitmap.prototype=new createjs.Bitmap();
//親クラスのinitializeを取得
SliseBitmap.prototype.Bitmap_initialize=SliseBitmap.prototype.initialize;
//親クラスの_tickを取得/必要か不明
SliseBitmap.prototype.Bitmap_tick=SliseBitmap.prototype._tick;
SliseBitmap.prototype.initialize=function(slice){
this.Bitmap_initialize(slice);
}
window.SliseBitmap=SliseBitmap;
}(window));
//------------------------------------------------------------------------------
//START
window.onload=function() {
var img=new Image();
img.src='/main/images/welcome_back5.png';
img.onload=function () {
welcome_result=img;
welcomeflag=true;
init();
};
img.onerror=function () {
welcome_result=img;
welcomeflag=false;
init();
};
};
注釈文を削除すれば、幾分早くなります。
登録画像パスは当方の場合です。使用の際は環境に合わせて下さい。
CSS
createJS048.css、CSS名は任意に変更可
/*日本語 createJS048.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;
}
当方のサンプルの例です。
簡単な説明
複数の形状の違う「画像分割」と「マスク要素」を組み合わせて画像エフェクトする
「画像分割」と「マスク要素」TransitionMaskエフェクトは同じような流れで処理されていますので、1つの処理系で組み合わせが出来ます。但し マスクの着色も組み合わせているため処理が面倒になっています。
以下、2つのJSを組み合わせて処理しています。処理の詳細は下記記事を参照下さい。
【参照】当方の記事: CreateJS 画像分割アニメーション、一括画像読み込み、toDataURL()を使用しない方式
【参照】当方の記事: CreateJS Transition Mask マスク要素を組み合わせてアニメ表示する、番外編
単なる番外編ですのでこのJSの詳細は省略します。このように複雑にすることは通常ないと思います。
自動分割
原則「自動分割」で使用します。
「自動分割」でない場合は登録の分割(1種類)で、分割データ0番として処理されますので、スライスまたはマスクモードで「画像分割」及び「楕円.角丸」のマスク処理を実行します。
登録の「free分割データ」も使用されませんし、カラーマスクも実行されません。
分割データ登録
「デモ」の自動分割のデータは以下の様になります。第一番目のデータは、予約されていますので、なるべく正方形に近くなる分割数を記載のこと。(楕円、角丸マスクの設定が行われます)
第二番目以降は自由です、同じ分割が多くあれば出現確率が増します。
//自動分割の場合、free分割データを登録/奇数値が良い
var splitHs=[11,11,10,7,5,11,11,2,2,1,1];
var splitVs=[5,5,6,3,3,2,1,2,4,9,1];
--------------------------------------------------------------------
11x5 5x3 の確率が増す、第一番目の確率は減る
var splitHs=[11,11,11,10,7,5,5,11,11,2,2,1,1];
var splitVs=[5,5,5,6,3,3,3,2,1,2,4,9,1];
分割は一般的に、奇数値でキレイになるように設計されています。
但し、4Doorタイプが中にありますのでこれは偶数値の場合にキレイになるようになっています。(2x2)
1枚画像(1x1)もなるべくキレイになるように一応は修正していますが、必ず全てに旨く合致するとは限りません。
画像分割、マスクの出現確率
画像分割、マスクの出現確率の初期値は次の様に成ります。書き換えれば確率が変わります。
//MODE登録
var mode_name=["slice","slice","mask"];
楕円、角丸マスクの出現確率
楕円、角丸マスクの出現確率は、上記MODE登録で mask 名が多ければ出現確率が高くなります。
または、第一番目以降の登録数が少なければ出現確率が高くなります。
var splitHs=[11,11,7];
var splitVs=[5,5,3];
他の分割も多くして、楕円、角丸マスクの出現確率のみ高くするには、処理途中で強制的に変更すれば可能ですが、そのようにはしていません。
カラーマスクの出現確率
カラーマスクの出現確率は次ぎの値(3以上)を小さくかえれば、出現率が増します。
//多目的用
var maskflag=Math.floor(Math.random()*5);//3以上
カラーマスクの場合には、マスク要素を addChild しないと見えません。
画像分割のBitmap継承クラス化
画像分割部分をのBitmap継承クラス化してみました。
以下の様にして使用してみました。但し、tick 部分は必要であるかは不明、削除しても使用できます。
1. 画像はloaderで得られたresult値です。
2. 位置、大きさを与えれば分割したBitmapを返します。(toDataURL()を使用しない方式)
3. 簡単にトリミングしたBitmapを得ることが出来ますので、他にも使い道はあると思います。
4. 一応使用出来るので作り方に問題はないものと思います。
//SliseBitmap(画像,分割位置X,Y,大きさ横,縦)
chip[k]=new SliseBitmap(mainImage,chip_pos_X[k],chip_pos_Y[k],chip_W[k],chip_H[k]);
-------------------------------------------------------------------------
//Bitmap継承SliseBitmapクラス
(function (window){
function SliseBitmap(img,pos_x,pos_y,c_w,c_h){
//
this.img=img;
this.pos_x=pos_x;
this.pos_y=pos_y;
this.c_w=c_w;
this.c_h=c_h;
//スライス
var slice=document.createElement("canvas");
slice.width=this.c_w;
slice.height=this.c_h;
var context=slice.getContext("2d");
context.drawImage(this.img,this.pos_x,this.pos_y,this.c_w,this.c_h,0,0,this.c_w,this.c_h);
this.initialize(slice);//Canvas要素
}
//Bitmap化
SliseBitmap.prototype=new createjs.Bitmap();
//親クラスのinitializeを取得
SliseBitmap.prototype.Bitmap_initialize=SliseBitmap.prototype.initialize;
//親クラスの_tickを取得/必要か不明
SliseBitmap.prototype.Bitmap_tick=SliseBitmap.prototype._tick;
SliseBitmap.prototype.initialize=function(slice){
this.Bitmap_initialize(slice);
}
window.SliseBitmap=SliseBitmap;
}(window));
AS2 Transitionクラス
Flash(AS2)にTransitionクラスがありましたから、それを意識してのことですが現時点では「CreateJS」でまだ全てを実行出来ないようです(半分は可能かな?)。
Canvas、CreateJSが進化すれば、将来は出来るのではと思っていますし誰かが作ることでしょう。
書き換えなどの変更
複雑になっていますのでかなり面倒です。処理を理解して独自に構築したほうが早いかもしれません。
処理は単純ですが、動かす条件がランダムですので、条件に合わない場合の修正と確認に時間がかかるだけです。
Tween処理部分も1つのループで処理出来ますが、繁雑になるので2つに分離しています。
十分なテストはしていませんので、多少処理が疎かな所がマレに出る可能性は有ります。(気が付かないかも!)
画像
画像は各自用意ください。写真画像 640x300サイズ、Welcome画像640x300サイズ
一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。
以上です。
[ この記事のURL ]