POPSブログ

CreateJS Reflection 鏡面効果

289

  Category:  javascript2014/04/07 pops 

CreateJS で作る、Reflection 鏡面効果です。名前の通り画像などが鏡面に写しだされた様な効果です。画像などをグラフイックのデータ(RGBA PNG32画像)とAlphaMaskFilter処理します。
Textでも結構効果がありますのでテスト的に表示してみました。
easeljs-0.7.1 でのテストです。

 

CreateJS Reflection 鏡面効果テスト


一時期に流行しましたが、このごろはあまり見かけません。一応作り方を検討します。Textでも効果をみてみました。
今回より、easeljs-0.7.1 を使用します。(easeljs-0.7.0でも問題はありません)


 

DEMO


CreateJS Reflection 鏡面効果デモ、(createJS073.js)

このページはHTML5では有りませんので、デモページでご覧ください。「IE7.8」ではご覧いただけません。
/// 注意、ブラウザ、マシン性能により描画品質などに大きな差が有ります事了承下さい ///


Chrome Opera Firefox Safari(Win) IE9-11で動作確認済み。 Safari(Mac)、は未確認です。


 

HTML JS CSS


使用するライブラリ

easeljs preloadjs tweenjs

配布元 : CreateJS createjs.com


ライブラリの読み込み

ダウンロードしたJSを使用する場合。記述は一例です。(バージョン 0.7.1 使用)


<script type="text/javascript" src="js/easeljs-0.7.1.min.js"></script>
<script type="text/javascript" src="js/preloadjs-0.4.1.min.js"></script>

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


HTML (HTML5)


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

JS

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


//日本語
//createJS073.js
//Reflection
//easeljs-0.7.1デモ用

//------------------------------------------------------
//初期設定
//canvasの大きさ
var canvasWidth=640;
var canvasHeight=400;

//説明TEXT
var textUse=true;

//画像リスト
var manifest=[
{src:"/main/images/textback03.jpg",id:"text"},
{src:"/main/images/textback12.png",id:"text"},
{src:"/main/images/textback13.png",id:"text"},
{src:"/main/images/testImage101.jpg",id:"text"},
{src:"/main/images/testImage102.jpg",id:"text"},
{src:"/main/images/testImage103.jpg",id:"text"},
{src:"/main/images/testImage104.jpg",id:"text"}
];

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

//ステージ
var stage;
var backrect;
//コンテナ
var mainContainer;
//簡易TEXT
var viewtext;
//画像容器
var assets=[];
var image_max;

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

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

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

	//STAGE
	stage=new createjs.Stage('mainCanvas');

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

	//Mainコンテナ
	mainContainer=new createjs.Container();
	stage.addChild(mainContainer);

	//簡易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);

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

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

}

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

	set_text("Loading Now!");
	//Loaderを作る
	var loader=new createjs.LoadQueue(false);
	//loader EventListener設定
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//Manifestを使用、Load開始
	loader.loadManifest(manifest);

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

	//result値
	assets.push(event.result);

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

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

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

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

	//画像があれば
	if (image_max) {

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

			//簡易TEXTクリア非表示
			set_text("");

			//表示に進む
			main();

		},1000);
	}
}

//Main
function main() {

	//reflection1表示
	reflection1();
	set_memo(20,20,"1 原点00 Bitmap");

	//reflection2表示
	reflection2();
	set_memo(150,20,"2 中央補正 Bitmap");

	//reflection2b表示
	reflection2b();
	set_memo(260,20,"2b 中央補正 BitmapFill");

	//reflection3表示
	reflection3();
	set_memo(390,20,"3 中央補 正Matix");

	//reflection4表示
	reflection4();
	set_memo(520,20,"4 中央補正 エレメント");

	//reflection5表示
	reflection5();
	set_memo(30,300,"5 アウトラインLogoText");

	//reflection6表示
	reflection6();
	set_memo(350,300,"6 通常LogoText、Impact文字");

	//reflection7表示
	reflection7();
	set_memo(340,200,"7 ベースつきLogoText");

}

//base Bitmap画像Reflectionコンテナなし原点0
function reflection1(){

	//パーツの大きさ
	var imageWidth=100;
	var imageHeight=100;

	var loadImage=assets[3];

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	//画像インスタンス
	var imagechips=new createjs.Bitmap(loadImage);

	//Reflectionコンテナなし

	//Bitmap画像
	var shadowchips=new createjs.Bitmap(loadImage);

	//グラフイックグラデ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);
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);

	shadowchips.y=imageHeight*2;
	shadowchips.scaleY=-1;
	shadowchips.alpha=0.75;

	bg.y=imageHeight;

	//配置
	chips.addChild(bg,shadowchips,imagechips);
	chips.x=20;
	chips.y=30;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//base Bitmap画像Reflectionコンテナなし中心補正
function reflection2(){

	//パーツの大きさ
	var imageWidth=100;
	var imageHeight=100;

	var loadImage=assets[4];

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	//画像インスタンス
	var imagechips=new createjs.Bitmap(loadImage);
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナなし

	//Bitmap画像
	var shadowchips=new createjs.Bitmap(loadImage);

	//グラフイックグラデ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);

	//食み出し修正
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);

	shadowchips.regX=imageWidth/2;
	shadowchips.regY=imageHeight/2;
	shadowchips.y=imageHeight;
	shadowchips.scaleY=-1;
	shadowchips.alpha=0.75;

	bg.regX=imageWidth/2;
	bg.regY=imageHeight/2;
	bg.y=imageHeight;

	//配置
	chips.addChild(bg,shadowchips,imagechips);
	chips.x=200;
	chips.y=80;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//base Bitmap画像shadowコンテナ収容形中心補正
function reflection2b(){

	//パーツの大きさ
	var imageWidth=100;
	var imageHeight=100;

	var loadImage=assets[4];

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	//画像インスタンス
	var imagechips=new createjs.Bitmap(loadImage);
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナ
	shadowbox=new createjs.Container();

	//Bitmap画像
 	//createImgCanvas
	var shadowchips=new createjs.Bitmap(createImgCanvas(imageWidth,imageHeight,loadImage));

	//グラフイックグラデ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);

	//食み出し修正
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);
	//配置、くせあり
	shadowbox.addChild(bg,shadowchips);
	shadowbox.regX=imageWidth/2;
	shadowbox.regY=imageHeight/2;

	shadowchips.scaleX=1;
	shadowchips.scaleY=-0.5;
	shadowbox.x=0;
	shadowbox.y=imageHeight*1.5;
	shadowbox.alpha=0.75;

	//配置
	chips.addChild(shadowbox,imagechips);
	chips.x=310;
	chips.y=80;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//base Bitmap画像/matrixReflection中心補正
function reflection3(){

	//パーツの大きさ
	var imageWidth=100;
	var imageHeight=100;

	var loadImage=assets[5];

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	//画像インスタンス
	var imagechips=new createjs.Bitmap(loadImage);
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナなし
	//グラフイックShape
	//BitmapFill
	var shadowchips=new createjs.Shape();
	var matrix=new createjs.Matrix2D();
	matrix.rotate(Math.PI);
	matrix.translate(imageWidth,imageHeight);

	//graphicsSHADOW画像
	shadowchips.graphics.beginBitmapFill(loadImage,"no-repeat",matrix).drawRect(0,0,imageWidth,imageHeight);
	shadowchips.regX=imageWidth/2;
	shadowchips.regY=imageHeight/2;
	shadowchips.x=0;
	shadowchips.y=imageHeight*3/4;
	shadowchips.scaleX=1;
	shadowchips.scaleY=-0.5;
	shadowchips.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);
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);
	shadowchips.alpha=0.75;

	//配置
	chips.addChild(imagechips,bg,shadowchips);
	chips.x=440;
	chips.y=80;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//base Bitmap画像shadowコンテナ収容形4中心補正
function reflection4(){

	//パーツの大きさ
	var imageWidth=100;
	var imageHeight=100;

	var loadImage=assets[6];

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	//画像インスタンス
	var imagechips=new createjs.Bitmap(loadImage);
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナ
	shadowbox=new createjs.Container();

	//Bitmap画像
 	//createImgCanvas
	var shadowchips=new createjs.Bitmap(createImgCanvas(imageWidth,imageHeight,loadImage));

	//CanvasグラデSHADOW
	var bg=new createjs.Bitmap(createLinearGradientCanvas(imageWidth,imageHeight));
	bg.cache(0,0,imageWidth,imageHeight);
	//食み出し修正
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);
	//配置
	shadowbox.addChild(bg,shadowchips);
	shadowbox.regX=imageWidth/2;
	shadowbox.regY=imageHeight/2;

	shadowchips.scaleX=1;
	shadowchips.scaleY=-0.5;
	shadowbox.x=0;
	shadowbox.y=imageHeight*1.5;
	shadowbox.alpha=0.75;

	chips.addChild(shadowbox,imagechips);
	chips.x=570;
	chips.y=80;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//アウトラインText中心補正
function reflection5(){

	//パーツの大きさ
	var imageWidth=300;
	var imageHeight=50;

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	var font_name="Arial";
	var font_name2="Impact";
	var font_name3="Serif";
	//var img=null;

	var img=assets[0];
	//Logo/Reflectionアウトライン専用
	//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影、パタン画像、ストリング
	var logo=createTextOutlineLogoR (imageWidth,imageHeight,"rgba(0,0,0,0)",font_name,"bold 46px","#FFFFFF","#FFFFFF",3,true,"#00BFFF",true,img,'POPS-WEB');

	//画像インスタンス
	var imagechips=new createjs.Bitmap(logo);
	//Bitmapコピー
	var shadowchips=imagechips.clone();
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナ
	shadowbox=new createjs.Container();

	//CanvasグラデSHADOW
	var bg=new createjs.Bitmap(createLinearGradientCanvas(imageWidth,imageHeight));
	bg.cache(0,0,imageWidth,imageHeight);
	//食み出し修正
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);
	//配置
	shadowbox.addChild(bg,shadowchips);
	shadowbox.regX=imageWidth/2;
	shadowbox.regY=imageHeight/2;

	shadowchips.scaleX=1;
	shadowchips.scaleY=-0.75;
	shadowbox.x=0;
	shadowbox.y=imageHeight*1.6;
	shadowbox.alpha=0.5;//alpha

	chips.addChild(shadowbox,imagechips);
	chips.x=160;
	chips.y=330;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//LogoText中心補正
function reflection6(){

	//パーツの大きさ
	var imageWidth=300;
	var imageHeight=50;

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	var font_name="Arial";
	var font_name2="Impact";
	var font_name3="Serif";
	//var img=null;

	var img=assets[1];
	//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影、パタン画像、ストリング
	var logo=createTextLogoCanvasR (imageWidth,imageHeight,"rgba(0,0,0,0)",font_name2,"bold 46px","#6496ED","#FFFFFF",2,true,true,img,'POPS-WEB');

	//画像インスタンス
	var imagechips=new createjs.Bitmap(logo);
	//Bitmapコピー
	var shadowchips=imagechips.clone();
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナ
	shadowbox=new createjs.Container();

	//CanvasグラデSHADOW
	var bg=new createjs.Bitmap(createLinearGradientCanvas(imageWidth,imageHeight));
	bg.cache(0,0,imageWidth,imageHeight);
	//食み出し修正
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);
	//配置
	shadowbox.addChild(bg,shadowchips);
	shadowbox.regX=imageWidth/2;
	shadowbox.regY=imageHeight/2;

	shadowchips.scaleX=1;
	shadowchips.scaleY=-0.75;
	shadowbox.x=0;
	shadowbox.y=imageHeight*1.6;
	shadowbox.alpha=0.5;//alpha

	chips.addChild(shadowbox,imagechips);
	chips.x=480;
	chips.y=330;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

//ベースつきLogoText中心補正
function reflection7(){

	//パーツの大きさ
	var imageWidth=300;
	var imageHeight=50;

	//画像とReflection収納コンテナ
	var chips=new createjs.Container();
	chips.id=1;

	var font_name="Arial";
	var font_name2="Impact";
	var font_name3="Serif";
	//var img=null;

	var img=assets[2];
	//html5角丸RoundRectCanvasを作るC/Chrome外からshadowだめ
	//ベースW、H、ボックスX、Y、幅、高さ、角丸半径、ボックス色、ライン色、ライン幅、ライン、陰影色、陰影X、陰影Y、陰影W、陰影、パタン画像、文字種、サイズ、文字色、文字陰影、ストリング
	//(bw,bh,x,y,w,h,r,bcolor,lcolor,lineW,line,scolor,sx,sy,sw,shadow,patternimg)
	var logo=createRoundRectCanvasTextBox_R (imageWidth,imageHeight,10,10,imageWidth-20,imageHeight-20,10,"#FFF8DC","#FFD700",2,true,"rgb(0,0,0)",0,0,7,true,img,font_name,"bold 24px","#FFFFFF",true,"POPS WEB KOUBOU");

	//画像インスタンス
	var imagechips=new createjs.Bitmap(logo);
	//Bitmapコピー
	var shadowchips=imagechips.clone();
	//中央補正
	imagechips.regX=imageWidth/2;
	imagechips.regY=imageHeight/2;

	//Reflectionコンテナ
	shadowbox=new createjs.Container();

	//CanvasグラデSHADOW
	var bg=new createjs.Bitmap(createLinearGradientCanvas(imageWidth,imageHeight));
	bg.cache(0,0,imageWidth,imageHeight);
	//食み出し修正
	bg.visible=false;

	//AlphaMaskFilter
	var amf=new createjs.AlphaMaskFilter(bg.cacheCanvas);
	shadowchips.filters=[amf];
	shadowchips.cache(0,0,imageWidth,imageHeight);
	//配置
	shadowbox.addChild(bg,shadowchips);
	shadowbox.regX=imageWidth/2;
	shadowbox.regY=imageHeight/2;

	shadowchips.scaleX=1;
	shadowchips.scaleY=-0.75;
	shadowbox.x=0;
	shadowbox.y=imageHeight*1.6;
	shadowbox.alpha=0.5;//alpha

	chips.addChild(shadowbox,imagechips);
	chips.x=480;
	chips.y=230;
	//mainContainer addChild
	mainContainer.addChild(chips);

}

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

//tick
function tick() {
	stage.update();
}
//VIEWTEXT
function set_text(t) {

	if (textUse) {
		viewtext.text=t;
		stage.update();
	}
}

//MEMOTEXT
function set_memo(x,y,t) {
	var text=new createjs.Text(t,"10px Arial","#FF0000");
	text.x=x;
	text.y=y;
	text.textBaseline="middle";
	stage.addChild(text);
}
//------------------------------------------------------------------------------

//LOGO-Canvasテキスト/Reflectionアウトライン専用/Safari補正済
//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影、パタン画像、ストリング
function createTextOutlineLogoR (w,h,c,font,fsize,fcolor,lcolor,lwidth,line,scolor,shadow,patternimg,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	if (!scolor) {scolor="#000000";}//陰影補正

	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに指定色陰影
	if (!scolor) {scolor="#000000";}//陰影補正

//shadowになる増強材
ctx.strokeStyle="#FFFFFF";//色は関係なし
ctx.lineWidth=4;
set_shadow2 (ctx,lcolor);
ctx.strokeText(text,w/2,h/2);

	//Safari補正用下層テキスト
	//shadow2
	if(shadow) {
		ctx.strokeStyle=scolor;
		set_shadow2 (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
		//set_shadow2 (ctx,scolor);
		//ctx.strokeText(text,w/2,h/2);//強調
		//ctx.compositeOperation="lighter";
	}

	//OUTLINE
	if(patternimg) {
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.strokeStyle=pattern;
	} else {
		ctx.strokeStyle=fcolor;
	}

	//TEXT-LINE
	ctx.lineWidth=lwidth;
	//陰影a=0で消す
	if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
	ctx.strokeText(text,w/2,h/2);

	return canvas;
}

//陰影Blur=7
function set_shadow2 (ctx,color) {

	//RGB変換
	rgbArr=toRgb(color);

	//Textに陰影
	//影の色オフセット距離ぼかし量
	//ctx.shadowColor="rgb(0,0,0)";

	//Graphics.getRGB利用した
	ctx.shadowColor=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2]);//OK
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=7;
}

//LOGO-TEXT付きCanvasを作る/Reflection専用
//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影、パタン画像、ストリング
function createTextLogoCanvasR (w,h,c,font,fsize,fcolor,lcolor,lineW,line,shadow,patternimg,text) {

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

	var font_v=fsize +" "+ font;

	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";


//グロー効果
/*
ctx.strokeStyle="#00BFFF";
ctx.lineWidth=5;
if (shadow) {set_shadow (ctx,"#00BFFF");}
ctx.strokeText(text,w/2,h/2);
*/


	if(patternimg) {
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.fillStyle=pattern;
	} else {
		ctx.fillStyle=fcolor;
	}


	//Textに陰影
	if (shadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,w/2,h/2);

	//TEXT-LINE
	if(line) {
		ctx.strokeStyle=lcolor;
		ctx.lineWidth=lineW;
		ctx.strokeText(text,w/2,h/2);
	}

	return canvas;
}

//TEXT付きcanvasを作る/Reflection専用
//ベースW、H、ボックスX、Y、幅、高さ、角丸半径、ボックス色、ライン色、ライン幅、ライン、陰影色、陰影X、陰影Y、陰影W、陰影、パタン画像、文字種、サイズ、文字色、文字陰影、ストリング
function createRoundRectCanvasTextBox_R(bw,bh,x,y,w,h,r,bcolor,lcolor,lineW,line,scolor,sx,sy,sw,shadow,patternimg,font,fsize,fcolor,tshadow,text) {
	//RoundRectBox
	var canvas=document.createElement("canvas");
	//ベースは大きい
	canvas.width=bw;
	canvas.height=bh;
	var ctx=canvas.getContext("2d");

	//arcTo処理未使用、間違いやすい
	//roundRectArcTo(ctx,x,y,w,h,r,r,r,r);
	//arc処理未使用、間違いやすい
	//roundRectArc(ctx,x,y,w,h,r);


	//html5 RoundRect/Opera OK
	ctx.beginPath();
	ctx.moveTo(x+r,y);
	ctx.lineTo(x+w-r,y);
	ctx.quadraticCurveTo(x+w,y,x+w,y+r);
	ctx.lineTo(x+w,y+h-r);
	ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h);
	ctx.lineTo(x+r,y+h);
	ctx.quadraticCurveTo(x,y+h,x,y+h-r);
	ctx.lineTo(x,y+r);
	ctx.quadraticCurveTo(x,y,x+r,y);
	ctx.closePath();

	ctx.lineCap="butt";
	ctx.fillStyle=bcolor;
	if(line) {
		ctx.strokeStyle=lcolor;
		ctx.lineWidth=lineW;
	}
	//shadow
	if(shadow) {
		ctx.shadowColor=scolor;
		ctx.shadowOffsetX=sx;
		ctx.shadowOffsetY=sy;
		ctx.shadowBlur=sw;
		//IE9画像ズレ対策
		if(patternimg){ctx.fillStyle=scolor;}
	}
	ctx.fill();
	//ラインに影を付けない
	if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}//
	//パタン画像
	if(patternimg){
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.fillStyle=pattern;
		ctx.fill();
	}
	if(line) {ctx.stroke();}

	//Text
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (tshadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,bw/2,bh/2);

	return canvas;
}

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

//ArcTo処理、未使用
function roundRectArcTo(c,x,y,w,h,r1,r2,r3,r4) {
	// assumes that r1..r4 are in range
	c.beginPath();
	c.moveTo(x+w/2,y);
	c.arcTo(x+w,y,x+w,y+h/2,r1);
	c.arcTo(x+w,y+h,x+w/2,y+h,r2);
	c.arcTo(x,y+h,x,y+h/2,r3);
	c.arcTo(x,y,x+w/2,y,r4);
	c.closePath();
	c.stroke();
}

//Arc処理、未使用
function roundRectArc(c,x,y,w,h,r){
	c.beginPath();
	c.moveTo(x,y+r);
	c.arc(x+r,y+h-r,r,Math.PI,Math.PI/2,1);
	c.arc(x+w-r,y+h-r,r,Math.PI/2,0,1);
	c.arc(x+w-r,y+r,r,0,Math.PI*3/2,1);
	c.arc(x+r,y+r,r,Math.PI*3/2,Math.PI,1);
	c.closePath();
	c.stroke();
}

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

//ImageCanvas/サイズを与えると自由な大きさを取れる
//Chrome OK
//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

//------------------------------------------------------------------------------
//陰影Blur=5
function set_shadow (ctx,color) {

	//RGB変換
	rgbArr=toRgb(color);

	//Textに陰影
	//影の色オフセット距離ぼかし量
	//ctx.shadowColor="rgb(0,0,0)";

	//Graphics.getRGB利用した
	ctx.shadowColor=createjs.Graphics.getRGB(rgbArr[0],rgbArr[1],rgbArr[2]);//OK
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=5;//3-5
}

//変換は配列で返す
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;
}

//幅、高さ、画像
function createImgCanvas(w,h,patternimg) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,0,0,w,h);

	return canvas;
}

//ライングラデCanvas
function createLinearGradientCanvas(w,h) {
	//Box
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	var gradient=ctx.createLinearGradient(w,h,w,0);
	gradient.addColorStop(0,"rgba(0,0,0,1)");
	gradient.addColorStop(1,"rgba(0,0,0,0)");
	ctx.fillStyle=gradient;
	ctx.fillRect(0,0,w,h);

	return canvas;
}
//--------------------------------------------------------------

//START
init();

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


CSS

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


/*日本語 createJS073.css*/

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

#image-box {
position:relative;
top:0;left:0;
width:640px;
height:300px;
margin:0 auto;
padding:0;
border:1px #CCCCCC solid;
background-color:#FFFFFF;
}

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


簡単な説明


Reflection 鏡面効果


簡単な、Reflection 鏡面効果です。画像とテキストで作ってみました。CreateJSでのMatrix処理は少々癖があるようですので、ほとんど、Matrixを使用しない方法で処理しています。
1つ、Matrixを使用のものがありますのでコードを比較してみてください。


[説明図]

 

1. 画像およびグラフイックのデータをキャッシュしてAlphaMaskFilter処理します。
(画像は必ず読み込み完了のもを使用するのが前提になります)
2. グラフイックのデータは邪魔なので非表示にします。
3. グラフイックのデータは、ほとんどShape()で作り、LinearGradientFill()で処理するのが通常と思いますが、CanvasエレメントでもOKのようです。
4. いろいろな形式で作ってみました。(半数は、Reflection部分を縮小できる様にしている)
5. 半数は、画像の中心を原点とするため、Reflection部分をまとめてコンテナ収容の形にしています。
(アニメーションさせる場合は、原点を画像中心にした方が容易です)
6. easeljs-0.7.0でも問題はありません。


AlphaMaskFilter処理

画像とグラフイックのデータを用意して、双方をキャッシュしてAlphaMaskFilter処理をする。
グラフイックインスタンスは「透明度情報を含むPNG32画像」。グラフイックインスタンスをShape()で作るのは「透明度情報を含むPNG32画像」を作るのと同意である。


● 透明度情報を含むグラフイックを作る
透明度情報が使用されるのであって、色は何でもよい。マスク材であるグラフイックはサンプルでは addChild しているが必ずしも addChild の必要はない。(位置合わせ確認のため addChild して、最終的には非表示にしている)


var bg=new createjs.Shape();
bg.graphics.beginLinearGradientFill(["rgba(0,0,0,0)","rgba(0,0,0,1)"],[0,1],0,0,0,高さ).drawRect(0,0,幅,高さ);

慣れない内は Graphicsクラス で作ったほうが無難と思います。(Graphicsクラスにしろ最終的にはPNG画像を作っているに過ぎない)


● AlphaMaskFilterの実行


//グラデーショングラフイック
グラフイックインスタンス.cache(0,0,幅,高さ);
グラフイックインスタンス.visible=false;

//AlphaMaskFilter
var amf=new createjs.AlphaMaskFilter(グラフイックインスタンス.cacheCanvas);
画像インスタンス.filters=[amf];
画像インスタンス.cache(0,0,幅,高さ);

● 透明度情報を含むCanvasエレメントを作る

Shapeグラフイックの代わりに「Canvasエレメント」で作ってもよいが、Bitmap()に取り込みキャッシュする。
「Canvasエレメント」を利用できる実証であって、どちらで作るかは自由である。


//Canvasエレメントグラデ
var bg=new createjs.Bitmap(createLinearGradientCanvas(幅,高さ));
bg.cache(0,0,幅,高さ);
//食み出し修正
bg.visible=false;

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

//ライングラデCanvas
function createLinearGradientCanvas(w,h) {
	//Box
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	var gradient=ctx.createLinearGradient(w,h,w,0);
	gradient.addColorStop(0,"rgba(0,0,0,1)");
	gradient.addColorStop(1,"rgba(0,0,0,0)");
	ctx.fillStyle=gradient;
	ctx.fillRect(0,0,w,h);

	return canvas;
}

画像のReflection

サンプルを5種類つくってみた。CreateJSでのMatrix処理は少々癖があるようですし、Matrix処理をしないほうが幾分簡単なようです。

1. Reflectionの高さは小さいほうが見て自然と思います。
2. Reflection全体の透明度は少し透過したほうが自然かも知れません。
3. Reflection全体を一括に作ったほうが、アニメーションの際に制御しやすいと思います。

目的に応じて作ればよいわけですが...


テキストのReflection

Canvasエレメントでテキストの画像を作り、Reflection処理をしてみた。3種類つくってみたが結構きれいに仕上がる。



1. アウトラインテキスト装飾

2. 通常テキスト装飾

3. 背景つきテキスト

以前作ったテキスト装飾用関数をReflection処理用に改造したものです。Safariの不具合に対応しています。
細やかな部分処理のために、Canvasエレメントで Canvas仕様 で描かれています。

 

アウトラインテキストのグロー処理効果

CreateJSにグロー処理はないが、グロー処理したような効果を出せないか考えてみた。(偶然にできた)

1. CreateJSにグロー処理はまだない。(グロー処理の追加できるJSは存在している)
2. 通常の陰影処理(黒以外の色でも)は、背景が黒いと効果がなくなる。
3. アウトラインテキストの場合のみ、少々工夫すると、グロー処理したような効果をつけることができる。
(ほかのものは、ラインと陰影をうまく最下位層に配置すると可能のようだ)
4. Fontの種類などによりますが、アウトラインの幅など大きくすると文字が壊れる場合があります。要確認。


Canvasエレメントでつくる、アウトラインテキストについては下記記事など参考にしてください。

【参照】当方の記事: CreateJS Canvasエレメント描画のOutlineテキストをBitmapクラスで表示する


● 通常処理

通常処理ではアウトラインの後ろに、陰影をつけて装飾しているが、薄いので2重に処理して強調している。
背景が黒いと、陰影が黒以外でも消えて見えない。
compositeOperation="lighter"は大きな効果はない。


//LOGO-Canvasテキスト/Reflectionアウトライン専用/Safari補正済
function createTextOutlineLogoR (w,h,c,font,fsize,fcolor,lcolor,lwidth,line,scolor,shadow,patternimg,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	if (!scolor) {scolor="#000000";}//陰影補正

	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに指定色陰影
	if (!scolor) {scolor="#000000";}//陰影補正

	//Safari補正用下層テキスト
	//shadow2
	if(shadow) {
		ctx.strokeStyle=scolor;
		set_shadow2 (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
		set_shadow2 (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);//強調
		//ctx.compositeOperation="lighter";
	}

	//OUTLINE
	if(patternimg) {
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.strokeStyle=pattern;
	} else {
		ctx.strokeStyle=fcolor;
	}

	//TEXT-LINE
	ctx.lineWidth=lwidth;
	//陰影a=0で消す
	if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
	ctx.strokeText(text,w/2,h/2);

	return canvas;
}

● グロー処理効果をつける (偶然にできたグロー効果)

アウトライン陰影の前にライン処理をしてみたら、その部分が透過せずに「グロー処理効果」のようになる。
ただし、色は指定しても無視されるが、うまく設定すればそれなりの効果はあると思う。ライン幅が大きいと文字が崩れるので注意。


//LOGO-Canvasテキスト/Reflectionアウトライン専用/Safari補正済
function createTextOutlineLogoR (w,h,c,font,fsize,fcolor,lcolor,lwidth,line,scolor,shadow,patternimg,text) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	if (!scolor) {scolor="#000000";}//陰影補正

	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	var font_v=fsize +" "+ font;

	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに指定色陰影
	if (!scolor) {scolor="#000000";}//陰影補正

//shadowになる増強材
ctx.strokeStyle="#FFFFFF";//色は関係なし
ctx.lineWidth=4;
set_shadow2 (ctx,lcolor);
ctx.strokeText(text,w/2,h/2);

	//Safari補正用下層テキスト
	//shadow2
	if(shadow) {
		ctx.strokeStyle=scolor;
		set_shadow2 (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
		//set_shadow2 (ctx,scolor);
		//ctx.strokeText(text,w/2,h/2);//強調
		//ctx.compositeOperation="lighter";
	}

	//OUTLINE
	if(patternimg) {
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.strokeStyle=pattern;
	} else {
		ctx.strokeStyle=fcolor;
	}

	//TEXT-LINE
	ctx.lineWidth=lwidth;
	//陰影a=0で消す
	if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
	ctx.strokeText(text,w/2,h/2);

	return canvas;
}

この技法は、当方のアーカイブ284記事、アウトラインテキストの陰影を濃くするのに応用できます。


通常テキストのグロー処理効果

アウトラインテキストでグロー処理効果は偶然にできたが、通常テキストではそのようにはいきません。
意図的に、テキスト最下位にグロー処理効果の出るようにラインを配置して陰影処理をします。

その時のテキストの装飾条件によって異なってきますが、文字など壊れない程度に配置します。要するにライン幅の調整で少しはみ出すようにするのがコツです。



//LOGO-TEXT付きCanvasを作る/Reflection専用
function createTextLogoCanvasR (w,h,c,font,fsize,fcolor,lcolor,lineW,line,shadow,patternimg,text) {

	略す

	//グロー効果
	ctx.strokeStyle="#00BFFF";
	ctx.lineWidth=5;
	if (shadow) {set_shadow (ctx,"#00BFFF");}
	ctx.strokeText(text,w/2,h/2);

	略す

}

テキスト背景を持つもの

テキストの後ろに背景を描画する場合は、Canvasエレメントの大きさより、陰影などの大きさを考慮して内側に描画しないと背景が途切れてしまうので注意しなければならない。
ブラウザによりますが、文字のY方向の位置が微妙に違いますのでご了承ください。


● RoundRect背景の例
角丸部分は quadraticCurveTo で描画しているがこのほうが簡単に描ける。Bitmap()に取り入れ表示させるが、Bitmap()に直接陰影処理した場合 Chrome では陰影は処理されない。
よって、原則「Canvasエレメント」描画内で陰影を処理する。


参考のために、arcTo処理、arc処理、での RoundRect背景の描画方法も入れていますが、quadraticCurveTo処理を推奨します。



//TEXT付きcanvasを作る/Reflection専用
//ベースW、H、ボックスX、Y、幅、高さ、角丸半径、ボックス色、ライン色、ライン幅、ライン、陰影色、陰影X、陰影Y、陰影W、陰影、パタン画像、文字種、サイズ、文字色、文字陰影、ストリング
function createRoundRectCanvasTextBox_R(bw,bh,x,y,w,h,r,bcolor,lcolor,lineW,line,scolor,sx,sy,sw,shadow,patternimg,font,fsize,fcolor,tshadow,text) {
	//RoundRectBox
	var canvas=document.createElement("canvas");
	//ベースは大きい
	canvas.width=bw;
	canvas.height=bh;
	var ctx=canvas.getContext("2d");

	//arcTo処理未使用、間違いやすい
	//roundRectArcTo(ctx,x,y,w,h,r,r,r,r);
	//arc処理未使用、間違いやすい
	//roundRectArc(ctx,x,y,w,h,r);

	//html5 RoundRect/Opera OK
	ctx.beginPath();
	ctx.moveTo(x+r,y);
	ctx.lineTo(x+w-r,y);
	ctx.quadraticCurveTo(x+w,y,x+w,y+r);
	ctx.lineTo(x+w,y+h-r);
	ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h);
	ctx.lineTo(x+r,y+h);
	ctx.quadraticCurveTo(x,y+h,x,y+h-r);
	ctx.lineTo(x,y+r);
	ctx.quadraticCurveTo(x,y,x+r,y);
	ctx.closePath();

	ctx.lineCap="butt";
	ctx.fillStyle=bcolor;
	if(line) {
		ctx.strokeStyle=lcolor;
		ctx.lineWidth=lineW;
	}
	//shadow
	if(shadow) {
		ctx.shadowColor=scolor;
		ctx.shadowOffsetX=sx;
		ctx.shadowOffsetY=sy;
		ctx.shadowBlur=sw;
		//IE9画像ズレ対策
		if(patternimg){ctx.fillStyle=scolor;}
	}
	ctx.fill();
	//ラインに影を付けない
	if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}//
	//パタン画像
	if(patternimg){
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.fillStyle=pattern;
		ctx.fill();
	}
	if(line) {ctx.stroke();}

	//Text
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (tshadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,bw/2,bh/2);

	return canvas;
}

 

ArcTo処理、arc処理の RoundRect背景

.quadraticCurveToを使用しない、arcTo処理、arc処理の RoundRect背景であるが、ともに間違いやすいので使用には注意が必要です。CreateJSの方法ではなく直接「Canvasエレメント」に描画する場合ですので間違いなきよう、
参考まで記載する。(ほとんど使用することは無いでしょう)


● ArcTo処理の場合は大変難しい

出典は、Stack Overflowの記事だが、URLが不明になった、以下の方法だとRoundRectが描ける、これは、四隅の弧の半径を指定できるのが強みである。引数でctxを渡して処理させる。

注意、Chrome用エンジン搭載でない、Operaでは正常に描画しません。現在ほとんどが「Chrome用エンジン」と思いますのでさほど注意の必要性はないが、...



var ctx=canvas.getContext("2d");
//ArcTo処理未使用、間違いやすい
roundRectArcTo(ctx,x,y,w,h,r,r,r,r);

--------------------------------------------------------------
//ArcTo処理、未使用
function roundRectArcTo(c,x,y,w,h,r1,r2,r3,r4) {
	// assumes that r1..r4 are in range
	c.beginPath();
	c.moveTo(x+w/2,y);
	c.arcTo(x+w,y,x+w,y+h/2,r1);
	c.arcTo(x+w,y+h,x+w/2,y+h,r2);
	c.arcTo(x,y+h,x,y+h/2,r3);
	c.arcTo(x,y,x+w/2,y,r4);
	c.closePath();
	c.stroke();
}

Operaのシェアはほとんどない。


● arc処理の場合も大変難しい

出典は、下記、paulowniaの記事だが、ArcTo処理と同様に間違いやすいので注意が必要だ。quadraticCurveToの使用が無難である。

【参考】paulowniaの記事: HTML Canvasに角丸の矩形を描く


参考記事のコードでは横幅、高さが反対に描画されるので、下記コードではその値を反対に設定した?



var ctx=canvas.getContext("2d");
//Arc処理未使用、間違いやすい
roundRectArc(ctx,x,y,w,h,r);

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

//Arc処理、未使用
function roundRectArc(c,x,y,w,h,r){
	c.beginPath();
	c.moveTo(x,y+r);
	c.arc(x+r,y+h-r,r,Math.PI,Math.PI/2,1);
	c.arc(x+w-r,y+h-r,r,Math.PI/2,0,1);
	c.arc(x+w-r,y+r,r,0,Math.PI*3/2,1);
	c.arc(x+r,y+r,r,Math.PI*3/2,Math.PI,1);
	c.closePath();
	c.stroke();
}

使用画像

使用画像は「デモ」ページにあります。


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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧



[1]