POPSブログ

CreateJS 3D Carousel もどき、Matrix2Dで画像などを回転させる

272

  Category:  javascript2014/01/15 pops 

円周上に配置したインスタンスを回転させる 3D Carousel もどきですが、画像を挿入して見ました。この手のものに定番である Reflection (鏡面効果)を付けてグローバルメニューとして使用するなどを想定した作りです。前ページの原型を発展させたものですが処理部分は同等です。
easeljs-0.7 でのテストです。

 

CreateJS 3D Carousel もどき、Matrix2Dで画像などを回転させる


easeljs-0.8よりMatrix2Dが大幅に変更になり、easeljs-0.7では動作しませんので「easeljs-0.8」用に書き直しました。
● 下記記事を参照ください。(archives338-344)

【参照】当方の記事: CreateJS Matrixで円周配置の図形Shapeなどを回転(easeljs-0.8)

【参照】当方の記事: CreateJS 3D風Carousel円周配置のインスタンスを回転させる(easeljs-0.8

【参照】当方の記事: CreateJS 3D風画像Carousel表示(easeljs-0.8) このページ記事と同様です

【参照】当方の記事: CreateJS 3D風画像CarouselのBlur処理(easeljs-0.8)

【参照】当方の記事: CreateJS 3D風Carousel画像拡大表示(easeljs-0.8)

【参照】当方の記事: CreateJS 3D風TEXT文字Carousel表示(easeljs-0.8)

【参照】当方の記事: CreateJS Matrix円周配置インスタンス回転(easeljs-0.8)

 

● 注意、以下はeaseljs-0.7対象です。

画像の読み込み、画像のReflection処理などを追加して有りますが、3D Carouselの部分は
前ページの「CreateJS 3D Carouselもどき原型」を参照下さい。


 

DEMO


CreateJS 3D Carousel もどき、Matrix2Dで画像などを回転させる テスト、(createJS057.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>

重要、バージョン違いでは動かない場合が有りますので必ず合わせて下さい。
このデモでは、tweenjs は必要では有りません。
尚、AlphaMaskFilterクラスは easeljs-0.7.0.min.js に内包されました。(すっかり忘れてた、2014/01/26訂正)


HTML (HTML5)


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

JS

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


//日本語
//createJS057.js
//Carouselデモ2
//easeljs-0.7用

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

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

//画像の大きさ
var imageWidth=100;
var imageHeight=100;
var margin=10;
//エラー画像の大きさ
var errorImageWidth=100;
var errorImageHeight=100;

//carouselの色
var carouselbackcolor="#FFFFFF";

//split分割数自動修正 3以上
var carouselsplit=12;

//半径
var radiusX=240;//X方向
var radiusY=80;//Y方向

//回転速度 デグリー値1-5
var angle=2;//DEG
//正転逆転フラグ 右正転=1 左逆転=-1
var carouselflag=1;
//マウスイベントの使用 true false
var eventUse=true;
//コンテナ角度
var containerAngle=0;
//パーツ角度
var partsAngle=0;
//虹色にする不透明 true false
var rainbowColor=false;
//画像シャドウReflection
var imageShadow=false;
//基本スケール
var stScale=0.75;
//始点の角度
var startAngle=-Math.PI/2;

//テキスト使用
var textUse=true;

//画像リスト100x100
var manifest=[
{src:"/main/images/testImage101.jpg",id:"PHOTO1"},
{src:"/main/images/testImage102.jpg",id:"PHOTO2"},
{src:"/main/images/testImage103.jpg",id:"PHOTO3"},
{src:"/main/images/testImage104.jpg",id:"PHOTO4"},
{src:"/main/images/testImage105.jpg",id:"PHOTO5"},
{src:"/main/images/testImage106.jpg",id:"PHOTO6"},
{src:"/main/images/testImage107.jpg",id:"PHOTO7"},
{src:"/main/images/testImage108.jpg",id:"PHOTO8"},
{src:"/main/images/testImage109.jpg",id:"PHOTO9"},
{src:"/main/images/testImage110.jpg",id:"PHOTO10"}

];


//--------------------------------------------------------------
//回転正逆補正
angle *=carouselflag;
//to-RAD
var rotate_angle=angle*createjs.Matrix2D.DEG_TO_RAD;
var plusAngle=-Math.PI/2;
//--------------------------------------------------------------

var stage;
var backimage;
var carouselContainer;
var progresscontainer;
var loadingShape;
var viewtext;

//matrix
var matrix=new createjs.Matrix2D();
var chip=[];
var chipAngle=[];
var innerchip=[];
var stopNo=1;

//画像
var assets=[];
var imagechip=[];
//ProgressBar変数
var bar_v=0;

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

function init() {

	stage=new createjs.Stage("mainCanvas");
	//MouseOver設定/必要に応じ設定
	stage.enableMouseOver(20);

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

	//空コンテナインスタンス配置
	carouselContainer=new createjs.Container();
	carouselContainer.x=canvasWidth/2;
	carouselContainer.y=canvasHeight/2;
	stage.addChild(carouselContainer);

	//簡易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_text("Carousel");

	//Loadingインスタンス配置2透明度
	loadingShape=loadingIndicator2(1);//右=1 左=-1
	loadingShape.x=canvasWidth/2;
	loadingShape.y=canvasHeight/2;
	//tickListenerを設定
	createjs.Ticker.setFPS(20);
	loadingShape.tick=function (){
		loadingShape.rotation +=angle;
		stage.update();
	};
	//loading addEventListenerを設定
	createjs.Ticker.addEventListener('tick',loadingShape.tick);
	stage.addChild(loadingShape);
	loadingShape.visible=true;

	//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を設定
	//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=canvasWidth/2;
	progresscontainer.y=canvasHeight/2;
	progresscontainer.addChild(progressbar,progtext);
	stage.addChild(progresscontainer);

	//画像一括ロード
	bulkload();

}

//progressBar
function progress(event) {

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

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

	//Loaderを作る
	var loader=new createjs.LoadQueue(false);
	//progressがあれば先に設定
	loader.addEventListener("progress",progress);

	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//error
	loader.addEventListener("error",loaderror);

	//Manifestを使用、Load開始
	loader.loadManifest(manifest);

}

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

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

//読み込みエラー
function loaderror (event) {

	//上が白で下が、指定色のグラデーション代替画像を作る
	var gradient_data={x0:0,y0:canvasHeight/2,x1:0,y1:0};
	//幅、高さ、色、色2、DATA、フォント作る、文字種、サイズ、文字色、ストリング
	var errorImage=createGradientCanvas2 (errorImageWidth,errorImageHeight,"#000000","#FFFFFF",gradient_data,true,"Arial","bold 12px","#FFFFFF","NONE");
	//代替画像を保存
	assets.push(errorImage);
}

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

	//画像数確認、再計算
	image_max=assets.length;
	carouselsplit=image_max;

	//簡易TEXT
	set_text("Loading End!");

	//loader Listener削除
	event.target.removeEventListener("fileload",fileload);
	event.target.removeEventListener("complete",complete);
	//error
	event.target.removeEventListener("error",loaderror);

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

	stage.update();

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

		//早すぎるので調整
		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;

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

		},1000);//500-3000
	}
}

//Carousel設定
function carousel_set() {

	//パーツを配置してBaseを作る/Bitmap画像
	set_baseCircle();
	//Shape画像shadow
	//set_baseCircle2();

	//コンテナを傾ける
	carouselContainer.rotation=containerAngle;

	//Listener
	createjs.Ticker.setFPS(40);
	createjs.Ticker.addEventListener("tick",carousel_rotate);

	//マウスイベントの使用
	if (eventUse) {
		stage.addEventListener("stagemousemove",setAngle);
	}

}

//マウスアクション
function setAngle(event) {
	var mouseX=event.stageX;
	angle=(mouseX-canvasWidth/2)*1/100;
}

//Ticker
function carousel_rotate(event) {

	var count=carouselsplit;

	//加算/停止処理
	plusAngle +=(angle*createjs.Matrix2D.DEG_TO_RAD*stopNo);

	//描画データ
	var cx,cy;
	var cAngle=startAngle;
	var nAngle=0;

	//描画位置
	nAngle=Math.PI*2/count;
	var chipflag=1;
	var parts_angle=0;

	//保存POSITION配列
	var posArr=[];
	//SORT用POSITION配列
	var zArr=[];
	//透明度用配列
	var alphaArr=[];

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

		//回転
		cAngle +=nAngle;

		cx=Math.cos(cAngle+plusAngle)*radiusX;
		cy=Math.sin(cAngle+plusAngle)*radiusY;

		//alpha-Data計算
		alphaArr[i]=(1+cy/radiusY)/2;

		//配置角度取得
		parts_angle=Math.atan2(cy,cx);

		//パーツ角度
		var angle_r=partsAngle*createjs.Matrix2D.DEG_TO_RAD;
		//伸縮1 Xスケールで向きを変える
		var scl=Math.cos(parts_angle+Math.PI/2)/Math.cos(Math.PI);//Xスケール
		//var scl=Math.cos(parts_angle+Math.PI/2);//Xスケール反対向き
		//伸縮2 遠近感を付ける
		//var sclxy=(Math.abs(Math.cos(parts_angle/2-Math.PI/4)/Math.cos(Math.PI))+1)/2;

		//position段階計算
		var a_v=1+(cy*0.25)/radiusY;
		posArr[i]=a_v;

		//sort-DATAを保存
		var id=chip[i].id;
		//オブジェクトで保存
		zArr.push({'id':id, 'position':cy});

		//matrix
		matrix.identity();
		//順序重要
		matrix.rotate(angle_r);

		//伸縮1
		//matrix.scale(scl*stScale,stScale);
		//伸縮2
		//matrix.scale(sclxy*stScale,sclxy*stScale);
		//position段階スケール
		matrix.scale(posArr[i]*stScale,posArr[i]*stScale);
		//基本スケール
		//matrix.scale(stScale,stScale);

		//位置をずらす
		matrix.translate(cx,cy);
		matrix.decompose(chip[i]);

	}

	//配列をソート/positionの昇順にsort
	zArr.sort(function(a,b) {
		var x=a.position;
		var y=b.position;
		return x > y ? 1 : -1;}
	);
	//INDEX alpha修正
	for (var i=0; i < zArr.length; i++){
		var idno=zArr[i].id;
		//Index
		carouselContainer.setChildIndex(chip[idno],i);
		//alphaシャドウが出る、訂正済み
		//chip[idno].alpha=alphaArr[idno]+0.2;
	}

	//その他の処理 update
	draw_carousel();

}

//base Bitmap画像shadowコンテナ収容形
function set_baseCircle() {

	//画像シャドウ
	if (imageShadow) {margin=0;}

	//パーツの大きさ
	var parts_w=imageWidth+margin;
	var parts_h=imageHeight+margin;
	//数
	var count=carouselsplit;

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

		//図形用インスタンス配置
		chip[i]=new createjs.Container();
		chip[i].id=i;

		//NO-SHADOW
		if (!imageShadow) {

			//Rect
			innerchip[i]=new createjs.Shape();

			//Rect
			//graphicRect(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,carouselbackcolor,rainbowColor,count,i);
			//RoundRect
			graphicRoundRect(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,10,carouselbackcolor,rainbowColor,count,i);
		}


		//Bitmap
		imagechip[i]=new createjs.Bitmap(assets[i]);
		//中央補正
		imagechip[i].regX=imageWidth/2;
		imagechip[i].regY=imageHeight/2;

		//NO-SHADOW
		if (!imageShadow) {
			chip[i].addChild(innerchip[i],imagechip[i]);
			//chip[i].shadow=shadow;//重い
		}

		//画像Reflection
		if (imageShadow) {

			//画像shadowコンテナ収容形/scale等で配置にクセあり
			shadowbox=new createjs.Container();
			//Bitmap画像
			var shadowchip=new createjs.Bitmap(assets[i]);
			//グラデSHADOW
			var bg=new createjs.Shape();
			bg.graphics.beginLinearGradientFill(["rgba(0,0,0,0)","rgba(0,0,0,1)"],[0,1],0,0,0,imageHeight).drawRect(0,0,imageWidth,imageHeight);
			bg.cache(0,0,imageWidth,imageHeight);

			//クセでalphaシャドウ食み出しが出る、これで修正できる
			bg.visible=false;

			//AlphaMaskFilter
			var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
			shadowchip.filters=[amf];
			shadowchip.cache(0,0,imageWidth,imageHeight);
			//配置、くせあり
			shadowbox.addChild(bg,shadowchip);
			shadowchip.scaleX=1;
			shadowchip.scaleY=-0.5;
			shadowbox.x=0;
			shadowbox.y=imageHeight*1.5;
			shadowbox.regX=imageWidth/2;
			shadowbox.regY=imageHeight/2;
			shadowbox.rotation=0;

			//逆に配置
			chip[i].addChild(shadowbox,imagechip[i]);
		}

		//addChild
		carouselContainer.addChild(chip[i]);

		//rollover
		chip[i].addEventListener("rollover",function () {
			stopNo=0;
		});
		//rollout
		chip[i].addEventListener("rollout",function () {
			stopNo=1;
		});
		//click
		chip[i].addEventListener("click",handleclick);

	}

}

//base2 Shape画像shadow
function set_baseCircle2() {

	//画像シャドウ
	if (imageShadow) {margin=0;}

	//パーツの大きさ
	var parts_w=imageWidth+margin;
	var parts_h=imageHeight+margin;
	//数
	var count=carouselsplit;

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

		//図形用インスタンス配置
		chip[i]=new createjs.Container();
		chip[i].id=i;

		//NO-SHADOW
		if (!imageShadow) {

			//Rect
			innerchip[i]=new createjs.Shape();

			//Rect
			//graphicRect(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,carouselbackcolor,rainbowColor,count,i);
			//RoundRect
			graphicRoundRect(innerchip[i],-parts_w/2,-parts_h/2,parts_w,parts_h,10,carouselbackcolor,rainbowColor,count,i);
		}


		//Bitmap
		imagechip[i]=new createjs.Bitmap(assets[i]);
		//中央補正
		imagechip[i].regX=imageWidth/2;
		imagechip[i].regY=imageHeight/2;

		//NO-SHADOW
		if (!imageShadow) {
			chip[i].addChild(innerchip[i],imagechip[i]);
			//chip[i].shadow=shadow;//重い
		}

		//画像Reflection
		if (imageShadow) {

			//BitmapFill
			var shadowchip=new createjs.Shape();
			var matrix3=new createjs.Matrix2D();
			matrix3.rotate(Math.PI);
			matrix3.translate(imageWidth,imageHeight);

			//SHADOW画像
			shadowchip.graphics.beginBitmapFill(assets[i],"no-repeat",matrix3).drawRect(0,0,imageWidth,imageHeight);
			shadowchip.regX=imageWidth/2;
			shadowchip.regY=imageHeight/2;
			shadowchip.x=0;
			shadowchip.y=imageHeight*3/4;
			shadowchip.scaleX=1;
			shadowchip.scaleY=-0.5;
			shadowchip.rotation=180;

			//グラデSHADOW/これはずれない
			var bg=new createjs.Shape();
			bg.graphics.beginLinearGradientFill(["rgba(0,0,0,1)","rgba(0,0,0,0)"],[0,1],0,0,0,imageHeight).drawRect(0,0,imageWidth,imageHeight);
			bg.regX=imageWidth/2;
			bg.regY=imageHeight/2;
			bg.x=0;
			bg.y=imageHeight*3/4;
			bg.scaleX=1;
			bg.scaleY=-0.5;
			bg.rotation=180;
			bg.cache(0,0,imageWidth,imageHeight);

			//AlphaMaskFilter
			var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
			shadowchip.filters=[amf];
			shadowchip.cache(0,0,imageWidth,imageHeight);
			chip[i].addChild(imagechip[i],bg,shadowchip);
		}

		//addChild
		carouselContainer.addChild(chip[i]);

		//rollover
		chip[i].addEventListener("rollover",function () {
			stopNo=0;
		});
		//rollout
		chip[i].addEventListener("rollout",function () {
			stopNo=1;
		});
		//click
		chip[i].addEventListener("click",handleclick);

	}

}

//CLICK処理
function handleclick (event) {

	var instance=event.target.parent;
	//押されたボタンは何番目か
	//var hit_no=instance.parent.getChildIndex(instance);
	//インスタンスにIDで番号をいれてあるなら
	var hit_no=instance.id;
	set_text("HIT-No: "+hit_no);

	setTimeout(function() {
		set_text("");
	},2000);
}

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

//Rect Graphics
function graphicRect(s,x,y,w,h,color,rainbow,len,no) {
	var c=color;
	if (rainbow) {
		c=createjs.Graphics.getHSL(no/len*360,100,50);//直接
	}
	//s.graphics.clear();
	s.graphics.beginFill(c).drawRect(x,y,w,h);
}
//RoundRect Graphics
function graphicRoundRect(s,x,y,w,h,r,color,rainbow,len,no) {
	var c=color;
	if (rainbow) {
		c=createjs.Graphics.getHSL(no/len*360,100,50);//直接
	}
	//s.graphics.clear();
	s.graphics.beginFill(c);operaRoundRect(s,x,y,w,h,r);
}

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

//代替Canvas
//幅、高さ、色、フォント作る、文字種、サイズ、文字色、ストリング
function createGradientCanvas2 (w,h,c,c2,data,make,font,fsize,fcolor,text) {

	//data
	var x0=data.x0;
	var y0=data.y0;
	var x1=data.x1;
	var y1=data.y1;
	//
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	var gradient=ctx.createLinearGradient(x0,y0,x1,y1);
	gradient.addColorStop(0,c);
	gradient.addColorStop(1,c2);
	ctx.fillStyle=gradient;
	ctx.rect(0,0,w,h);
	ctx.fill();

	if (make) {

		var font_v=fsize +" "+ font;

		ctx.fillStyle=fcolor;
		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		ctx.fillText(text,w/2,h/2);

	}

	return canvas;
}

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

//--------------------------------------------------------------
//簡単なLOADING
function loadingIndicator2 (angle_v) {

	var loadingbackcolor="#CCCCCC";
	//16進カラーをrgbの形式に変換
	var rgbArr=toRgb(loadingbackcolor);
	//graphicのスタイル
	var graphics=new createjs.Graphics();
	graphics.setStrokeStyle(2,"round");//round

	//描画データ
	var rotateflag=1;
	if (angle_v < 0){rotateflag=-1};//逆転

	var alpha_v=1;//透明度
	var alphaback;

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

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

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

		alphaback=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2],alpha_v);
		//alphaback=createjs.Graphics.getRGB(204,204,204,alpha_v);

		//虹色計算alpha無し
		//alphaback=createjs.Graphics.getHSL(i/numNeedles*360,100,50);

		cx=Math.cos(cAngle)*innerR;
		cy=Math.sin(cAngle)*innerR;
		graphics.beginStroke(alphaback).moveTo(cx,cy);
		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		graphics.lineTo(cx,cy);

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

//変換は配列で返す
function toRgb(bc) {
	bc=bc.replace("#","");
	var rgbArr=[];
	rgbArr[0]=parseInt(bc.slice(0,2),16);
	rgbArr[1]=parseInt(bc.slice(2,4),16);
	rgbArr[2]=parseInt(bc.slice(4,6),16);
	return rgbArr;
}

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

init();

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


CSS

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


/*日本語 createJS056.css*/

#demo-wrap {
position:relative;
width:auto;
height:320px;
text-align:center;
}

#image-box {
/*position:absolute;*/
position:relative;
top:0;left:0;
width:640px;
height:300px;
padding:0;
margin:0 auto;
box-shadow:0 0 10px #000;
-moz-box-shadow:0 0 10px #000;
-webkit-box-shadow:0 0 10px #000;
-o-box-shadow:0 0 10px #000;
-ms-box-shadow:0 0 10px #000;
background-color:#000000;
}

#image-box #mainCanvas {
border-radius:10px;
}

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

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


簡単な説明


[説明図]

 

Container()インスタンスを作り外周に配置して並べている簡単な作りで、中にShape()インスタンス、画像等を収容して、Matrixで外周位置を変化させて回転する仕組みです。
CreateJSのMatrix(Matrix2Dクラス)は3Dに対応していませんので、重なり順をtick毎に修正しています。動きが3Dに見えますが実際には2Dで出来ています。
3D Carouselの詳細部分は「前ページの原型」を参照下さい。


1. 画像ですから、Reflection (鏡面効果)をも取り入れてみました。
2. 挿入画像は、Bitmap画像とShape流し込み画像の2種類の処理を書いています。
3. 「画像読み込み」に失敗した場合に「代替画像」を作るようにしています。
4. 一応 easeljs-0.7.1でも可動します。


【参照】当方の記事: CreateJS 3D Carousel もどき、Matrix2Dで円周上に配置したインスタンスを回転させる


画像の挿入

画像の挿入は別段に問題は有りませんが、MENUなどに使用する場合に仮に「画像読み込み」に失敗した場合に使用出来なくなりますので、代替画像を挿入する仕組みにしています。
画像リスト(manifest)に間違ったURL記述をすれば、出力する「代替画像」を確認できます。


1. 画像の大きさを登録します。標準スケール設定で大きさは変えられます(コンテナ)。
2. 画像の大きさは収納するコンテナの大きさになります。
3. 各種のmatrix処理などは、コンテナに対して行なわれます。
4. コンテナの余白は margin で調整できます。Reflection処理の場合 margin は無視されます。


画像処理は、Bitmap画像、Shape流し込み画像、の2種類作ってみました。
角丸図形 又は、marginを付ける場合は、Reflection処理を行わないようにしてください。
Reflection処理する場合で作り(構造)が違うと位置合わせなど少しクセが有ります、ここではReflectionの高さを半分にしているためにクセの影響が大きいようです。


1. set_baseCircle()関数、Bitmap画像形、shadowコンテナ収容形、(Reflection処理付き)。
2. set_baseCircle2()関数、Shape流し込み画像形、(Reflection処理付き)。

どちらを選んでも、表示結果は同じです。



//Carousel設定
function carousel_set() {

	略す

	//パーツを配置してBaseを作る/Bitmap画像
	set_baseCircle();

	略す

}

代替画像

画像読み込みエラー発生時に「代替画像」を作るようにしています。(キャンバス要素)
必要で無い場合は「読み込みエラー」関連の処理を削除する。
「代替画像」は下記の様に色、中の文字など指定できます。


//読み込みエラー
function loaderror (event) {

	//上が白で下が、指定色のグラデーション代替画像を作る
	var gradient_data={x0:0,y0:canvasHeight/2,x1:0,y1:0};
	//幅、高さ、色、色2、DATA、フォント作る、文字種、サイズ、文字色、ストリング
	var errorImage=createGradientCanvas2 (errorImageWidth,errorImageHeight,"#000000","#FFFFFF",gradient_data,true,"Arial","bold 12px","#FFFFFF","NONE");
	//代替画像を保存
	assets.push(errorImage);
}

Reflection (鏡面効果)

AlphaMaskFilter処理をしますが、AS3と比較すれば面倒ですし、キャッシュしなければならない手間隙が掛かる。
今回は、画像の高さを半分にして使用しましたが、CreateJSでは、位置合わせなどに少し工夫がいるようです。
(Reflection画像を縮小しなければ問題は出ない、あるいは少ないと思う)


1. AlphaMaskFilter処理対象の画像などのインスタンスを用意する。
2. 透明度を段階的に変えるために、データ用のShape()グラフイックを用意する。
3. グラフイックをキャッシュする。
4. マスク材は原則「非表示」にする。(マスク材が見えてしまう場合がある)
5. AlphaMaskFilterの実行。



//画像Reflection
if (imageShadow) {

	//画像shadowコンテナ収容形/scale等で配置にクセあり
	shadowbox=new createjs.Container();
	//Bitmap画像
	var shadowchip=new createjs.Bitmap(assets[i]);
	//グラデSHADOW
	var bg=new createjs.Shape();
	bg.graphics.beginLinearGradientFill(["rgba(0,0,0,0)","rgba(0,0,0,1)"],[0,1],0,0,0,imageHeight).drawRect(0,0,imageWidth,imageHeight);
	bg.cache(0,0,imageWidth,imageHeight);

	//クセでalphaシャドウ食み出しが出る、これで修正できる
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchip.filters=[amf];
	shadowchip.cache(0,0,imageWidth,imageHeight);
	//配置、くせあり
	shadowbox.addChild(bg,shadowchip);
	shadowchip.scaleX=1;
	shadowchip.scaleY=-0.5;
	shadowbox.x=0;
	shadowbox.y=imageHeight*1.5;
	shadowbox.regX=imageWidth/2;
	shadowbox.regY=imageHeight/2;
	shadowbox.rotation=0;

	//逆に配置
	chip[i].addChild(shadowbox,imagechip[i]);
}

Reflection画像の大きさ(高さ)を半分にしているために少し繁雑だ。大きさを変えないほうが簡単。


アクション設定

MENUなどに使用する事を想定して、アクション設定をしています。


1. 画像 MouseOver時、回転が停止します。
2. 画像 Click時、インスタンスのID番号を表示します 。



//rollover
chip[i].addEventListener("rollover",function () {
	stopNo=0;
});
//rollout
chip[i].addEventListener("rollout",function () {
	stopNo=1;
});
//click
chip[i].addEventListener("click",handleclick);

インスタンスのスケール変更など


多少見え方を変更できるようにしています。該当箇所を有効にすれば良いが、計算などは適当なものですから個人が工夫してください。(「position段階スケール」等の呼称も適当です、旨く表現する言葉が無い)
初期は、遠近感を付けた「position段階スケール」実行になっています。以下、前ページと内容はほぼ同じです。


● スケール関連


基本スケール

//基本スケール
var stScale=0.75;

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

計算

//伸縮1 Xスケールで向きを変える
var scl=Math.cos(parts_angle+Math.PI/2)/Math.cos(Math.PI);//Xスケール
//var scl=Math.cos(parts_angle+Math.PI/2);//Xスケール反対向き

//伸縮2 遠近感を付ける
var sclxy=(Math.abs(Math.cos(parts_angle/2-Math.PI/4)/Math.cos(Math.PI))+1)/2;

//position段階計算
var a_v=1+(cy*0.25)/radiusY;
posArr[i]=a_v;


//伸縮1実行
//matrix.scale(scl*stScale,stScale);

//伸縮2実行
//matrix.scale(sclxy*stScale,sclxy*stScale);

//position段階スケール実行
matrix.scale(posArr[i]*stScale,posArr[i]*stScale);

//基本スケール実行
//matrix.scale(stScale,stScale);

● 透明度関連

最後の数値を変えると、上方(遠方)の透明度を調整することが可能です。初期状態では使用していません。


	//INDEX alpha修正
	for (var i=0; i < zArr.length; i++){
		var idno=zArr[i].id;
		//Index
		carouselContainer.setChildIndex(chip[idno],i);
		//alpha
		//chip[idno].alpha=alphaArr[idno]+0.2;
	}

● ブラー関連

ぼかし処理も可能と思いますが?、実際に処理はしていません。キャッシュしなければならないので抵抗がある。
そのため「上記」の様に透明度で変化させた。


テスト的に、Blur(ぼかし)処理をしてみた。重い!!

【参照】当方の記事: CreateJS 3D Carousel もどき、画像のBlur処理


景観方向を変える

現在は、上方より俯瞰した状態で表示しています。下方から見上げる景観にするには、次ぎの変更で可能です。
1. 半径Y方向値をマイナス設定にする。
2. 配列のソートを降順にする。



//半径
var radiusX=240;//X方向
var radiusY=-80;//Y方向

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

//配列をソート/positionの降順にsort
zArr.sort(function(a,b) {
	var x=a.position;
	var y=b.position;
	return x < y ? 1 : -1;}
);

回転速度、正転逆転

回転速度、正転逆転等は初期設定で設定可能ですが、マウスイベントの使用ではマウス位置により、強制的に変更なります。
マウスイベントでの回転速度の変更は直接、関数中の値を変更下さい。


//回転速度 デグリー値1-5
var angle=2;//DEG
//正転逆転フラグ 右正転=1 左逆転=-1
var carouselflag=1;
//マウスイベントの使用 true false
var eventUse=true;

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

//マウスアクション
function setAngle(event) {
	var mouseX=event.stageX;
	angle=(mouseX-canvasWidth/2)*1/50;
}

これらの改造などは自由です。



 

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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]