CreateJSを利用して、HTML5のCanvasで画像を分割してアニメーションさせます。前回までのものと余り変わりは有りませんが、ステージを1つにして、レーヤー階層(コンテナ)等標準化しました。
エフェクトは単純なものにしました、最大の違いは、一括画像読み込み、分割画像の重ね順を「出現順序」に変更しました。
CreateJS Canvas画像分割アニメーション4 のテスト
2013/09/25/EaselJSなどバージョンUPされました(easeljs-0.7)。動作など確認してeaseljs-0.7用に更新しています。(2013/10/10)
基本的には、AS3、jQuery、で制作した「slice-photo」などをHTML5のCanvas仕様に書き換えたものです。ライブラリとしてCreateJSを利用しました。これは、下図のように多分割(正方形)にあうように調整しています。
easeljs-0.7.0用に書き換え、toDataURL()を使用しない形にしました。幾分処理が速くなりましたし、toDataURL()の対応していないブラウザでもOKです。
[ 目次 ]
Canvas画像分割アニメ一括画像読み込み単純階層化タイマー形式
1.DEMO
3.簡単な説明
画像分割でtoDataURL()を使用しない方式に関する説明
4.toDataURL()を使用に関すること (問題点、利点)
6.関連ページ記事
尚、toDataURL()を使用しない方式への修正方法を、この記事ページ終段 [5] に記載します。
DEMO
▲[ 目次 ]

角丸陰影CSS3、通常の画像処理より軽い、透過しても軽い、長い時間のアニメもOK、回転が出来る、拡大縮小が出来る、一括画像読み込み方式。
このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。
DEMO1 通常表示形式(説明文削除、簡単)
DEMO2 TEXT説明文表示形式(前の形式、複雑)
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
createJS006.js、JS名は任意に変更可、少し効率化していますが動きは同じです。ProgressBarなし。
//日本語
//createJS006.js
//easeljs-0.7用
//------------------------------------------------------
//初期設定
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;
//canvasの大きさ/全てこの値を使用
var canvasWidth=640;
var canvasHeight=300;
//タイマーの使用、useであること
var timer_use="use";
//タイマー値 5000-10000
var time=8000;
//テキスト表示の使用 use=true
text_use=true;//true false
//skew処理の分割トータル数、未使用
var skew_max=55;
//自動分割の場合、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];
//画像manifestリスト
var manifest=[
{src:"/main/images/toyota_car10.jpg",id:"PHOTO1"},
{src:"/main/images/toyota_car11.jpg",id:"PHOTO2"},
{src:"/main/images/toyota_car12.jpg",id:"PHOTO3"},
{src:"/main/images/toyota_car13.jpg",id:"PHOTO4"},
{src:"/main/images/toyota_car15.jpg",id:"PHOTO5"},
{src:"/main/images/toyota_car16.jpg",id:"PHOTO6"}
];
//------------------------------------------------------
//ステージ
var stage;
//画像インスタンス
var mainImage;
//コンテナ
var container;
var backcontainer;
var loadingcontainer;
var textcontainer;
//ローダー
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 once=false;
var viewtext;
//loading変数
var loading=false;
//最初の画像0のこと
var image_no=0;
//画像数
var image_max;
//Shadowフイルター
var shadow=new createjs.Shadow("#000000",0,0,4);
//ステージ周りセット
function init() {
//STAGE
stage=new createjs.Stage('mainCanvas');
//バックRect/最下位色背景層、無くとも良い
var backrect=new createjs.Shape();
//backrect.graphics.beginFill("#000000").drawRect(0,0,canvasWidth,canvasHeight);
backrect.graphics.beginFill().drawRect(0,0,canvasWidth,canvasHeight);
stage.addChild(backrect);
//下画像層、空画像コンテナを作る
backcontainer=new createjs.Container();
backImage=new createjs.Bitmap();
backcontainer.addChild(backImage);
stage.addChild(backcontainer);
//スライス画像層、空コンテナを作る、使いまわし
container=new createjs.Container();
stage.addChild(container);
//TEXTコンテナ
textcontainer=new createjs.Container();
viewtext=new createjs.Text("TEXT","12px Arial","#FFFFFF");
viewtext.x=20;
viewtext.y=18;
viewtext.lineWidth=canvasWidth-40;
viewtext.lineHeight=20;
viewtext.textBaseline="bottom";
stage.addChild(viewtext);
//テキスト陰影
viewtext.shadow=shadow;
text_set("");
//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() {
text_set("");
stage.update();
//画像表示
draw();
},1000);
}
}
//DRAW、アニメ
function draw() {
text_set("AUTO");
globalflag=false;
//IN OUTを確率で決定
inType=true;
var in_no=Math.floor(Math.random()*2);
if (in_no == 0) {inType=false;}
//最初の画像はIN
if (!once) {
inType=true;
once=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];
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.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(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++) {
//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++;
}
}
//OUTの場合下画像を入れる
if (!inType) {
backImage.image=new createjs.Bitmap(keep_mainImage).image;
}
//Firefox
setTimeout(function() {
//Ticker設定
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener('tick',tick);
},20);
}
//重ね順を一番上にする
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();
//eventObject.resul保存
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);
}
}
//TEXT表示
function text_set (t) {
if (text_use) {
viewtext.text=t;
stage.update();
}
}
//簡単な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
createJS006.css、CSS名は任意に変更可
/*日本語createJS006.css*/
#demo-wrap {
position:relative;
width:auto;
height:320px;
text-align:center;
}
#image-box {
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;
background-image:url('/main/images/welcome_black.png');
}
#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;
}
当方のサンプルの例です。背景画像使用の場合は用意ください。
簡単な説明
▲[ 目次 ]
使用する事は可能ですが、あくまでもテストですので個人の判断で使用ください。
テキストで説明文表示を削除しました
当初、テキスト登録説明文を画像毎に表示出来る様にしていましたが、テキストの品質が悪く使い難い事も有り、機能を削除しました。以前の形式は「デモ2」に掲載しておきます。
むしろ、説明文などは、DOMElementクラスで表示した方がキレイで自由度がまします。下記ページ参照。
【参照】当方の記事: CreateJS 画像スライド、アニメーション DOMElementクラスでテキスト表示
簡単な説明など
1. 前ページなどの画像分割アニメーションを比較的アニメを単純なものにしました。ほぼ正方形の分割にあうように調整しています。分割は自由に登録できますが、アニメが合わない場合もあります。
2. 一括画像読み込み方式に変更しましたので、当初の表示まで時間を要します。画像枚数は5枚前後を想定しています。(実際サーバー環境での読み込み時間が問題だ)
3. 分割画像の重ね順を出現時に一番上にしますので、不自然な感じが無くなりました。(現在全て修正済み)
4. ランダムに条件を変えますので、一部合わない場合も有り得ます(それなりに趣向があると無理に理解ください)。ランダム条件ですので中々出現しないパターンも有ります。
5. 階層化、レーヤー階層のことですが、レーヤーは有りませんのでコンテナを仮想レーヤーとして利用して階層化しました。使用しない階層も含みますが、一応標準化することにより他にも利用出来ると思います。
6. 画像リストの、「id」は使用していません。リスト登録の際「, 」に注意。
7. 外側の角丸処理はマスクで処理可能ですが、ギザギザが出て汚いので少々重くなるがCSS3で処理しました。(将来は改善されるだろうが、、)
8. 注意、直接Cデスク上では、Chrome が実行しない場合あり。ローカルサーバー上ではOKです。
基本的に5階層構成にしました。(レーヤー階層)
1. 最下位色背景層(Back背景着色用)
2. 下画像層(IN OUTのために画像を切り替える)
3. 上画像層(メインの分割画像処理用)
4. テキスト層(簡単なテキスト表示用、必要なら使用する)
5. ローデング層(ローデング収容)
● 簡単なLoading
loadingShape.tickの形式です。Ticker.addEventListener()も記述をあわせます。
変数、loadingで制御出来るようにしています。インスタンスの直下に書けるので便利。
//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表示判定
Tickerの削除は
createjs.Ticker.removeEventListener('tick',loadingShape.tick);
● 分割画像の重なり順の変更
.call(indexchg)
-----------------------------------------------
//重ね順を一番上にする
function indexchg () {
container.setChildIndex(this,split_all-1);
//container.setChildIndex(this,0);
}
このJSでは、setChildIndex(this,0) でも可能。
●テキスト層
テキスト表示使用可能です。Loadingの代わりに使用しても良い。JS先頭の設定で利用しないようにも出来ます。文字の長さは、横幅の70%位の一行です。
ブラウザにより解釈が違うようで、テキストの大きさ、テキスト品質、対応状況など「バラ付き」が有るようです。複数行の表示は避けたほうが良いと思います。(つまり役に立たない)
●下画像の処理
IN OUT、があるので下画像層に入れる画像が違います。2層を旨く使ってエフェクトをするようにしています。
下画像をBitmap()形式で処理して、removeChild()しないで、直接Bitmap()の中のimageのみ流しこむ方法、重なり順序が変わらないので便利だ。グラフイックの場合も同じ手法です。
但し、インスタンスbackImageが、Bitmap()形式で事前に収納されている事が条件です。
初期の状態、空Bitmap()を入れてある
//下画像層、空画像コンテナを作る
backcontainer=new createjs.Container();
backImage=new createjs.Bitmap();
backcontainer.addChild(backImage);
stage.addChild(backcontainer);
--------------------------------------------------------------
更新、中身のみすりかえ
//OUTの場合下画像を入れるstage.updateはしないこと
if (!inType) {
backImage.image=new createjs.Bitmap(keep_mainImage).image;
}
//Tween全てが完了してから下画像表示
if (inType) {
backImage.image=new createjs.Bitmap(mainImage).image;
stage.update();
}
●画像読み込みエラー処理
画像が取得出来ない場合は、URL情報を保存しないようにしている。(画像が取得出来ない事はほとんど無い)
よって、エラー処理することも余り無い。必要な場合はエラー処理をすれば良い。
fileload は push() で処理したほうが良いと思う。取得出来ない画像URLは保存されないから安心だ。
//各画像読み込み完了
function fileload (eventObject) {
//エラー無しの画像をassets容器に保存
assets.push(eventObject.result);
}
通常の処理でmanifestを有効にしてロードした場合、「id」の取得出来ない場合は対象画像は無い。
● サンプル外側ラップDIV層の背景画像について
サンプルでは、外側ラップ層 #image-box に背景画像を入れています。もし透過させたい場合は、最下位色背景層のRect背景を非表示にすると、最初背景画像#image-boxの上に描画します。(この構造で追加のコンテナなど無い場合)
仮にCanvasに非対応ブラウザの代替画像に成るだろう事も考慮しました。(非対応ブラウザではCanvasを実行しないので、外側ラップ層 #image-box に背景画像を表示する)
init() 最初のあたり
通常は黒背景になっている、他ではbackImageBoxを代用
//最下位色背景層Rect
backrect.graphics.beginFill("#000000").drawRect(0,0,canvasWidth,canvasHeight);
最初に透過させたい、色がつきません
backrect.graphics.beginFill().drawRect(0,0,canvasWidth,canvasHeight);
または、非表示にするなら下記でも良い
backrect.visible=false;
キャンバス非対応のブラウザの場合は、JSを実行できないために、代替の画像としても使えるかも!
● 直接画像を表示するには
Bitmap() で画像を表示でき読み込み次第表示する。画像が無くともエラーにならない所が便利だ。拠り確実にするには事前に new Image() を実行するなどの工夫が必要です。
色々な画像処理の中には、完全に画像を読み込んでいないと「エラー」になる事が多い。
画像を読み込み次第表示する
var welcomeImage;
//welcome画像層画像表示
welcomeImage=new createjs.Bitmap('/main/images/welcome_black_w.png');
stage.addChild(welcomeImage);
--------------------------------------------------------------
正確ではないので、注意が必要、十分な時間がいる
//Imageオブジェクト先読み
var backgroundimage=new Image();
backgroundimage.src="/main/images/welcome_black.png";
//welcome画像層画像表示
welcomeImage=new createjs.Bitmap(backgroundimage);
stage.addChild(welcomeImage);
--------------------------------------------------------------
画像の読み込みが出来なければ、全部実行できない
//Imageオブジェクト先読み
var backgroundimage=new Image();
backgroundimage.onload=function() {
init();
};
backgroundimage.src="/main/images/welcome_black.png";
//welcome画像層画像表示
welcomeImage=new createjs.Bitmap(backgroundimage);
stage.addChild(welcomeImage);
無理にキャンバス処理しないで、CSSで表示の手もある!
● 画像は各自ご用意ください。デモでは640x300サイズ
toDataURL()を使用に関すること
▲[ 目次 ]
toDataURL()を使用した場合の問題点
画像をBitmap化する場合は、toDataURL()を使用するのが正式な方法ですが、以下の様な問題が起こります。
1. 処理に時間がかかる、特にChromeでは顕著である。
(邪道ではあるが、toDataURL()を使用しなければ早い、下の2つの問題も出ない)
2.Firefoxで一瞬画像をキャンバス最上層に表示するバグが出る。(画像処理が遅いのか?)
(TwennのTicker処理を20-50ミリ秒遅らせると解決する)
3.CSSでの角丸部分(四隅)で、画像の overflow:hidden が機能せず食み出す。
(分割画像インスタンスを一括してコンテナに収容すると解決する)
Firefoxでのバグ解決法。但し確認できないブラウザもあるので、toDataURL()を使用しない場合でも、一応処理しておく、遅延が20-50ミリ秒だから影響は無い。
//OUTの場合下画像を入れる
if (!inType) {
backImage.image=new createjs.Bitmap(keep_mainImage).image;
}
//Firefox
setTimeout(function() {
//Ticker設定
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener('tick',tick);
},20);
toDataURL()を使用しない方式の利点
1. toDataURL()の対応していないブラウザでもOKです。
2. 処理時間が早い。
3. 外部画像を分割処理出来る。(toDataURL()は出来ない)
toDataURL()を使用しない方式で作ったBitmap
但し、この方法は偶然に機能しているだけで、邪道である?。分割画像インスタンスは正式なBitmapではないので、何らかの加工処理を行えばエラーになる場合がある?。
toDataURL()をしないで画像を処理したと仮定する
//画像を保存している
var image_v=sliceCanvas;
//画像の取替え
backImage.image=new createjs.Bitmap(image_v).image;
一時、Operaで「エラー」になった? その他のブラウザでは問題が無かった。これがその時の実情!。
「追記」、
正式なBitmapではないが、2日かけて、キャンバス要素の加工の色々なテストをして見たが問題は無いようである。タマタマOperaが一時狂っただけかも知れない。(履歴などは1回実行毎に削除して作業しているし再確認もした、たまにこの様な状況はある、マシン再起動で直ったり、その日の天気が悪かったのだろう、、エラーも意味不明だったし、)
但し、何らかの処理過程で「エラー」が絶対に出ないとは断言出来ない。重要なので追記する。2013/10/15
toDataURL()を使用した処理にしたい場合
処理が遅くなりますが、このページでの「デモ」JSでは以下の様にします。
画像分割貼り付けのループ内の記述
toDataURL()を使用する
context.drawImage(mainImage,..............);
srcArr[k]=sliceCanvas.toDataURL("image/png");
//srcArr[k]=sliceCanvas;
toDataURL()を使用しない方式への修正
▲[ 目次 ]
toDataURL()を使用しない方式への修正方法
他ページの画像分割の toDataURL() を使用しない方式への修正方法です。順次書き換えますが、修正前のものは以下の様にすれば良い。スプリクト記述は殆んど同じと思います。
画像をdrawImage()で分割している部分です、2箇所書き換えます。
var sliceCanvas=document.....は必ず移動下さい。
修正前
//画像分割貼り付け
var srcArr=[];//URL容器
var sliceCanvas=document.createElement("canvas");
var k=0;
for (var i=0; i < split_h; i++) {
for (var j=0; j < split_v; j++) {
//大きさ重要
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");
k++;
}
}
修正後
//画像分割貼り付け
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;
k++;
}
}
以上の修正です。
関連ページ記事
▲[ 目次 ]
toDataURL()を利用しない画像トリミング、画像複数分割、等については、下記ページの記事を参照下さい。
【参照】当方の記事: CreateJS 画像をトリミング(又は分割)してBitmap処理、Tweenさせる処理を考える
【参照】当方の記事: CreateJS 画像を分割(複数)してBitmap処理、Tweenさせる処理を考える
このページのJS(createJS006.js)書き換えまでの代替JS、 ProgressBar付きで殆んど同じです。
【参照】当方の記事: CreateJS 画像分割アニメーション、一括画像読み込み、toDataURL()を使用しない方式 (easeljs-0.7用)
バージョンUP(easeljs-0.7)に伴う変更点など。
【参照】当方の記事: CreateJS バージョンUP(easeljs-0.7)に伴う「デモ」の変更点
一応、完動しますが全てテストです。効率化のため、予告無くJSなど修正する場合がありますので了承下さい。
また、CreateJSの「仕様」もクルクル変わっていますので、バージョン違い等に充分注意下さい。
以上です。
[ この記事のURL ]