POPSブログ

CreateJS CanvasエレメントでCompositeOperation合成テキスト表示

323

  Category:  javascript2014/09/28 pops 

CreateJSで、テキストでマスクする場合CompositeOperation合成をすると簡単ですが、実際には他のステージの要素にも影響が及びうまく行きません。Canvasエレメントで処理してBitmapで表示すれば意外に実用的です。
easeljs-0.7.1 でのテストです。

 

CreateJS CanvasエレメントでCompositeOperation合成テキスト

通常、CreateJSで構成したステージの要素に対して、CompositeOperation合成をした場合に予期せぬ状態になったりと非常に困難で、自由に使いこなせないと思います。
テキストでマスクする場合、テキストをグラフイックで描画すれば良いが、準備が煩雑で制約もあります。
アニメーションには不向きですが「Canvasエレメント」で処理してBitmapで表示すれば意外に実用的です。


サイト内「セアカゴゲグモ」徘徊中、「キンチョール」「フマキラー」など持参の上、閲覧ください。

 

▼[ 簡単な説明の目次に進む ]

 

DEMO

▼[ 目次 ]


CreateJS CanvasエレメントでCompositeOperation合成テキスト表示デモ

このページは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>
<script type="text/javascript" src="js/tweenjs-0.5.1.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

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

以下、デモのJSとは一部違いがあります。


//日本語
//createJS106.js
//CompositeOperationフォントで画像をマスクするテスト
//easeljs-0.7.1用

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

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

//画像manifestリスト
var manifest=[
{src:"/main/images/textback01.jpg",id:"text"},
{src:"/main/images/textback02.jpg",id:"text"},
{src:"/main/images/textback03.jpg",id:"text"},
{src:"/main/images/textback04.jpg",id:"text"},
{src:"/main/images/textback05.jpg",id:"text"},
{src:"/main/images/textback06.jpg",id:"text"},
{src:"/main/images/textback07.jpg",id:"text"},
{src:"/main/images/textback08.jpg",id:"text"},
{src:"/main/images/textback09.jpg",id:"text"},
{src:"/main/images/textback10.png",id:"text"},
{src:"/main/images/textback11.png",id:"text"},
{src:"/main/images/textback12.png",id:"text"},
{src:"/main/images/textback13.png",id:"text"},
{src:"/main/images/textback14.jpg",id:"text"},
{src:"/main/images/textback15.png",id:"text"},
{src:"/main/images/sky_back2.jpg",id:"photo"},
{src:"/main/images/green.jpg",id:"photo"}
];

//------------------------------------------------------
//変数、未使用もあり

//ステージ
var stage;
//コンテナなど
var backrect;
var backImage;
//
var maskImage,maskImage2,maskImage3,maskImage4;
var maskText,maskText2,maskText3,maskText4;
var maskcontainer,maskcontainer2,maskcontainer3,maskcontainer4;
var container;
//TEXT
var viewtext;
//読み込み画像URL保存容器
var assets=[];
var backphotos=[];
var loader;
var image_max;

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

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

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

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

	//背景画像1
	backImage=new createjs.Bitmap();
	stage.addChild(backImage);
	backImage.visible=true;

	//表示コンテナ
	//1
	maskcontainer=new createjs.Container();
	stage.addChild(maskcontainer);

	//2
	maskcontainer2=new createjs.Container();
	stage.addChild(maskcontainer2);

	//3
	maskcontainer3=new createjs.Container();
	stage.addChild(maskcontainer3);

	//4
	maskcontainer4=new createjs.Container();
	stage.addChild(maskcontainer4);

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

	stage.update();

	createjs.Ticker.setFPS(30);
	createjs.Ticker.addEventListener('tick',tick);

	//調整
	setTimeout(function() {

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

	},1000);

}

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

	//Loader
	loader=new createjs.LoadQueue(false);

	//loader EventListener設定、この部分修正
	loader.addEventListener("fileload",fileload);
	loader.addEventListener("complete",complete);
	//Manifestを使用、manifest読み込み開始
	loader.loadManifest(manifest);

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

	var id=event.item.id;
	//エラー無しの画像をassets容器に保存
	//画像選別
	if (id == 'text') {
		//result値
		assets.push(event.result);
	}
	if (id == 'photo') {
		//result値
		backphotos.push(event.result);
	}

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

	set_text("LOADING END!");
	//画像数確認、再計算
	image_max=assets.length;

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

	//背景画像表示
	backImage.image=new createjs.Bitmap(backphotos[1]).image;

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

			set_text("");

			//ひとつだけ有効にします

			//MAINに進む/サンプル1 2 3、
			set_maintext();

			//MAIN2に進む/サンプル4
			//set_maintext2();

			//MAIN3に進む/サンプル5
			//set_maintext3();

			//MAIN3に進む/サンプル6
			//set_maintext4();

		},1000);
	}

}

//MAIN
function set_maintext() {

/*
//TESTコンテナ1/これは旨く行かない/削除
maskcontainer.x=0;
maskcontainer.y=0;
maskImage.image=new createjs.Bitmap(assets[0]).image;
maskText=new createjs.Text("maskText","50px Arial","#FFFFFF");
maskText.textAlign="center";
maskText.textBaseline="middle";
maskText.x=640/2;
maskText.y=100/2;
maskcontainer.addChild(maskText);
maskText.compositeOperation="destination-out";//source-in/destination-in/destination-out
*/


	//---------サンプル1-----------------------------------
	//文字分解し再配置
	var text_pos=0;//右位置
	var text_spc=-2;//テキストスペース、重なり注意
	var center=true;//中央補正

	//destination-out/xor以外は効果なし
	//TESTコンテナ1
	maskcontainer.x=0;
	maskcontainer.y=0;
	var img=assets[0];

	//destination-outとxorのみ
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、スペース、中央補正
	maskText=new createjs.Bitmap(composite_text(640,100,"#CCCCCC","Impact","65px","#FF0000","POPS WEB KOUBOU",img,"destination-out",text_pos,text_spc,center));
	maskcontainer.addChild(maskText);

	//---------サンプル2-----------------------------------
	//TESTコンテナ2/Safari(win)NG/Safari Mac iPad一応OK
	maskcontainer2.x=0;
	maskcontainer2.y=60;
	var img=assets[1];
	var text_pos=0;//右位置
	var center=true;//中央補正

	//destination-in
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、中央補正
	maskText2=new createjs.Bitmap(composite_canvas(640,100,"#CCCCCC","Arial","Bold 40px","#FF0000","POPS WEB KOUBOU",img,"destination-in",text_pos,center));
	maskcontainer2.addChild(maskText2);
	maskText2.shadow=shadow;//陰影Chromeはだめ

	//---------サンプル3-----------------------------------
	//TESTコンテナ3
	maskcontainer3.x=0;
	maskcontainer3.y=200;
	var img=assets[9];
	var text_pos=0;//右位置
	var center=true;//中央補正

	//destination-out/xor
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、中央補正
	maskText3=new createjs.Bitmap(composite_canvas(640,100,"#CCCCCC","Arial","50px","#FF0000","POPS WEB KOUBOU",img,"destination-out",text_pos,center));
	maskcontainer3.addChild(maskText3);

}

//MAIN2
function set_maintext2() {

	//---------サンプル4-----------------------------------
	//TESTコンテナ4
	maskcontainer4.x=0;
	maskcontainer4.y=0;

	//原点中央補正のみ
	var img=backphotos[0];
	var scale=2;//拡大
	var angle=Math.PI/12;//角度

	//destination-out/xorのみ/注意Safari(win) destination-in NG/Safari Mac iPad一応OK
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、拡大、角度
	maskText4=new createjs.Bitmap(composite_canvas_S(640,300,"#CCCCCC","Impact","60px","#FF0000","POPS WEB KOUBOU",img,"destination-in",scale,angle));
	maskcontainer4.addChild(maskText4);
	maskText4.shadow=shadow;//陰影、Chrome NG

}

//MAIN3
function set_maintext3() {

	//---------サンプル5-----------------------------------
	//TESTコンテナ4
	maskcontainer4.x=0;
	maskcontainer4.y=0;

	//文字分解し再配置/原点中央補正のみ
	var text_spc=-10;//テキストスペース、重なりOK
	var img=backphotos[0];
	var scale=2;//拡大
	var angle=Math.PI/12;//角度

	//destination-out/xorのみ
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、拡大、角度
	maskText4=new createjs.Bitmap(composite_text_S(640,300,"#CCCCCC","Impact","60px","#FF0000","POPS WEB KOUBOU",img,"destination-out",text_spc,scale,angle));
	maskcontainer4.addChild(maskText4);
	maskText4.shadow=shadow;//陰影、Chrome NG

}

//MAIN4/特殊
function set_maintext4() {

	//---------サンプル6-----------------------------------
	//TESTコンテナ4
	maskcontainer4.x=0;
	maskcontainer4.y=0;

	//文字分解し再配置/原点中央補正のみ
	var text_spc=-10;//テキストスペース、重なりOK
	var img=backphotos[0];
	var scale=2;//拡大
	var angle=Math.PI/12;//角度

	//destination-in/destination-out
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、スペース、拡大、角度
	maskText4=new createjs.Bitmap(composite_canvas_W(640,300,"#CCCCCC","Impact","60px","#FF0000","POPS WEB KOUBOU",img,"destination-in",text_spc,scale,angle));
	maskcontainer4.addChild(maskText4);
	//Text描画ぼかすとChromeでの陰影が可能だ
	maskText4.shadow=shadow;//陰影、本来Chrome NG

}

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

//VIEWTEXT
function set_text(t) {
	viewtext.text=t;
}

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

//汎用処理用1/スペース設定はない
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、中央補正
function composite_canvas(w,h,c,font,fsize,fcolor,text,img,composite,text_pos,center) {

	var align="left";
	if(center) {align="center";text_pos=w/2;}

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(img,0,0,w,h);
	//TEXT
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign=align;
	ctx.textBaseline="middle";
	ctx.globalCompositeOperation=composite;
	//Text
	ctx.fillText(text,text_pos,h/2);

	return canvas;
}

//汎用処理用2/中央専用
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類
function composite_canvas2(w,h,c,font,fsize,fcolor,text,img,composite) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(img,0,0,w,h);
	//TEXT
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	ctx.globalCompositeOperation=composite;
	//Text
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

//汎用処理用3分解配置
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、スペース、中央補正
function composite_text(w,h,c,font,fsize,fcolor,text,img,composite,text_pos,space,center) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(img,0,0,w,h);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	var tpos_x=text_pos;//右位置
	var tpos_y=h/2;

	//中央補正
	if(center) {
		var alltext_width=0;
		ctx.font=font_v;
		var alltext_width=ctx.measureText(text).width+(text.length-1)*space;//全幅取得暫定計算
		ctx.fillText("",0,0);
		//ほぼ中央
		tpos_x=(w-alltext_width)/2;
	}

	//分解配置
	for (var i=0; i < text.length; i++) {

		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		var tx=text.charAt(i);
		var fw=ctx.measureText(tx).width;//幅取得
		//X位置
		tpos_x +=fw/2;

		//Text描画
		ctx.globalCompositeOperation=composite;
		ctx.fillText(tx,tpos_x,tpos_y);

		//位置加算
		tpos_x +=fw/2+space;//half+space
	}

	return canvas;
}

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

//文字回転形分解なし中央補正
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、拡大、角度
function composite_canvas_S(w,h,c,font,fsize,fcolor,text,img,composite,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);
	//背景
	ctx.drawImage(img,-w/2,-h/2,w,h);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;

	ctx.scale(scale,scale);
	ctx.rotate(angle);

	//TEXT描画
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	ctx.globalCompositeOperation=composite;
	//Text
	ctx.fillText(text,0,0);

	return canvas;
}

//文字回転形分解配置原点中央のみ
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、スペース、拡大、角度
function composite_text_S(w,h,c,font,fsize,fcolor,text,img,composite,space,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);
	//背景
	ctx.drawImage(img,-w/2,-h/2,w,h);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	var tpos_x=0;//中央位置
	var tpos_y=h/2;

	//強制中央補正
	var alltext_width=0;
	ctx.font=font_v;
	var alltext_width=ctx.measureText(text).width+(text.length-1)*space;//全幅取得暫定計算
	ctx.fillText("",0,0);
	//ほぼ中央の補正値
	pos_v=alltext_width/2;

	ctx.scale(scale,scale);
	ctx.rotate(angle);

	//分解配置
	for (var i=0; i < text.length; i++) {

		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		var tx=text.charAt(i);
		var fw=ctx.measureText(tx).width;//幅取得
		//X位置
		tpos_x +=fw/2;

		//Text描画
		ctx.globalCompositeOperation=composite;
		ctx.fillText(tx,tpos_x-pos_v,0);//X補正

		//位置加算
		tpos_x +=fw/2+space;//half+space
	}

	return canvas;
}

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

//特殊
//文字回転形分解配置原点中央のみ/画像で合成
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、スペース、拡大、角度
function composite_canvas_W(w,h,c,font,fsize,fcolor,text,img,composite,space,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);
	//背景
	ctx.drawImage(img,-w/2,-h/2,w,h);
	//Text画像描画取得
	var image=textCanvas_W(w,h,c,font,fsize,fcolor,text,space,scale,angle);
	ctx.globalCompositeOperation=composite;
	//合成
	ctx.drawImage(image,-w/2,-h/2,w,h);

	return canvas;
}
//幅、高さ、色、文字種、サイズ、文字色、ストリング、スペース、拡大、角度
function textCanvas_W(w,h,c,font,fsize,fcolor,text,space,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	var tpos_x=0;//中央位置
	var tpos_y=h/2;

	//強制中央補正
	var alltext_width=0;
	ctx.font=font_v;
	var alltext_width=ctx.measureText(text).width+(text.length-1)*space;//全幅取得暫定計算
	ctx.fillText("",0,0);
	//ほぼ中央の補正値
	pos_v=alltext_width/2;

	ctx.scale(scale,scale);
	ctx.rotate(angle);

	//set_shadow (ctx,"#FFFFFF");//ぼかすとChromeでの陰影が可能だ

	//分解配置
	for (var i=0; i < text.length; i++) {

		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		var tx=text.charAt(i);
		var fw=ctx.measureText(tx).width;//幅取得
		//X位置
		tpos_x +=fw/2;

		//Text描画
		//set_shadow (ctx,"#FFFFFF");//ぼかすとChromeでの陰影が可能だ
		ctx.fillText(tx,tpos_x-pos_v,0);//X補正

		//位置加算
		tpos_x +=fw/2+space;//half+space
	}

	return canvas;
}

//--------------------------------------------------------------------------------------
//LinearGradientBox
//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
function createLineGradBox (w,h,color1,color2,color3,direction,type) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");

	//LinearGradient
	var gradient;
	if(direction == 'x') {
		gradient=ctx.createLinearGradient(0,h,w,h);
	}
	if(direction == 'y') {
		gradient=ctx.createLinearGradient(w,0,w,h);
	}
	if(direction == 'xy') {
		gradient=ctx.createLinearGradient(0,0,w,h);
	}
	if(type == 2) {
		gradient.addColorStop(0,color1);
		gradient.addColorStop(1,color2);
	}
	if(type == 3) {
		gradient.addColorStop(0,color1);
		gradient.addColorStop(0.5,color2);
		gradient.addColorStop(1,color3);
	}
	ctx.fillStyle=gradient;
	//FILL
	ctx.fillRect(0,0,w,h);

	return canvas;
}
//色画像
//全幅、全高さ、背景色
function createColorCanvas(w,h,c) {
	//Box
	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;
}
//幅、高さ、画像
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;
}
//トリミング画像、X、Y、幅、高さ、
function imageTrimmingCanvas(patternimg,sx,sy,sw,sh,dx,dy,dw,dh) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=sw;
	canvas.height=sh;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,sx,sy,sw,sh,dx,dy,dw,dh);

	return canvas;
}

//Textに陰影BlurRGB変換なし
function set_shadow (ctx,color) {

	ctx.shadowColor=color;//OK
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=5;//3-5
}

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

//START
init();

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


CSS

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


/*日本語 createJS106.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;
}

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


 

簡単な説明


[説明図]

 

[ 簡単な説明の目次 ]


 

テキストでマスクする

▲[ 目次 ]


CompositeOperation合成で簡単にマスクなどの処理が出来るとは言いますが、合成の影響を受ける部分が多く、私自身実際には旨く行きませんので諦めかけました。
そこで、「Canvasエレメント」で「CompositeOperation合成」で処理して「Canvasエレメント」を「Bitmap」で表示すれば、画像化されますが使用するには実用的です。


1. 「Canvasエレメント」で処理してBitmapで表示のため他の要素に影響がない。
2. テキストで逆マスクする場合など簡単である。(画像を文字で抜く)
3. 但し、簡単なフエード、スライドは可能だが、アニメーションには向きません。
4. 完全な「マスク材」では有りませんが、あとは、アイデア次第です。
5. CreateJSでの、「マスク材」はグラフイックで描画するのが規則です。テキストではマスクは出来ない。
6. CompositeOperationは、ブラウザにより機能しないものもあるので、確認が必要です。


テキストをグラフイックで描画して「マスク」する場合は少々面倒です、下記記事を参照ください。

【参照】当方の記事: CreateJS フォントマスクと、Webフォントテキストアニメーション2

【参照】当方の記事: CreateJS フォントをGraphicsクラスで描画する


CreateJSでのCompositeOperation処理はうまく行かない

下記の様に、処理しますとCompositeOperationは機能しますが、ステージ下位の要素にまで影響があり、実用的な処理はスコブル困難です。CompositeOperation機能の解説は多々ありますが、ステージでの実際処理に関連する記事はほとんど有りません。lighterは良く使用されるようですが、CreateJSでは少し工夫がいるようです。


画像maskImageに対して、テキストmaskTextを上に重ねて、destination-out合成した場合の例。
実用にはなりません!。(上図、右参照)
ちなみに、黒の部分は下位の層を突き破り、ステージ用「Canvasエレメント」をラップしている「DIV」の背景色であるから驚く!、処理は非常に困難!



//1
maskcontainer=new createjs.Container();
maskImage=new createjs.Bitmap();
maskcontainer.addChild(maskImage);
stage.addChild(maskcontainer);
-------------------------------------------------------------------------
//TESTコンテナ1/これは旨く行かない
maskcontainer.x=0;
maskcontainer.y=0;
maskImage.image=new createjs.Bitmap(assets[0]).image;
maskText=new createjs.Text("maskText","50px Arial","#FFFFFF");
maskText.textAlign="center";
maskText.textBaseline="middle";
maskText.x=640/2;
maskText.y=100/2;
maskcontainer.addChild(maskText);
maskText.compositeOperation="destination-out";

source-in/destination-in/destination-outであれ、ステージ下位に影響が及び、実用的ではなく「ギブアップ」「お手上げ」です。

次バージョンからは、html5Canvas処理も、CreateJSスタイルで処理出来るように成りますので其の時の「合成用」のものであると言えば納得も出来ます。但し下記の様に、「Canvasエレメント」で処理の方が」簡単です。


「Canvasエレメント」で処理してBitmapで表示

そこで、「Canvasエレメント」で処理するテストを行いました。

「Canvasエレメント」で処理しますので、表示は当然Bitmapクラスで行います。出来上がりは画像そのものですからアニメーションには不向きですが、表示するだけなら実用的であり、ステージ下位に影響を及ぼさない。


1. 汎用処理用はテキストを横に配置するだけです。テキストの位置は指定可能。
2. 文字回転形はテキストを中央配置にしています。テキストの伸縮回転が出来ます。
3. テキスト分解配置はテキストの間隔を制御できますが、合成の種類が限定されます。
(destination-outを指定します、特殊形はdestination-inも可能)

4. 画像が必要ですが、「Canvasエレメント」の大きさは画像の大きさになります。
5. 書き換えなど自由ですから、実際の配置などを考慮したオリジナルの作成も可能です。
6. 陰影は、親のBitmapインスタンスに処理できます。(画像のためChromeは綺麗にならない)
7. Webフォントの使用は当然可能です。(デモ、サンプル7参照)
8. Safari(Win)はNGが多い、Safari(Win)は未確認ですがOKと思います。
(Safari(Win)を使用している方はいないと思います)


テキストを横に配置形、(伸縮回転なし)

▲[ 目次 ]


 

合成は原則、「destination-out」「destination-in」ですが、composite種類を指定できますが、この場合ブラウザの確認が必要です。(指定が全て旨く行くとは限りません)
「デモ」サンプル2、サンプル3、


● Bitmapクラスで表示する
「Canvasエレメント」で作りますので、Bitmapクラスで表示できます。
サンプル3 の例では、640,100の大きさで作っています。画像はグラデ状に透明度のあるPNG画像です(アルファチャンネル画像)。「destination-out」でテキスト部分が抜かれます。(逆Maskと言うべきか)
「destination-in」でテキスト部分が画像で染め上げられます(Mask)。テキスト位置は「Canvasエレメント」の中心に配置されます。画像は共にテキスト位置と同じになりますから判り易い。




//TESTコンテナ3
maskcontainer3.x=0;
maskcontainer3.y=200;
var img=assets[9];
var text_pos=0;//右位置
var center=true;//中央補正

//destination-out/xor
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、中央補正
maskText3=new createjs.Bitmap(composite_canvas(640,100,"#CCCCCC","Arial","50px","#FF0000","POPS WEB KOUBOU",img,"destination-out",text_pos,center));
maskcontainer3.addChild(maskText3);

● 画像の配置について
「Canvasエレメント」の中で画像を配置表示していますが、画像は大きさにかかわらず、「Canvasエレメント」の大きさに伸縮配置されます。
つまり、原則「Canvasエレメント」の大きさの画像を用意することになります。



ctx.drawImage(img,0,0,w,h);

● Maskとの違い
CreateJSの処理での Mask は原則、グラフイックで作りますので、テキストなどを利用するのは困難です。またブラウザによっては「ギザギザ」に処理されます。
CompositeOperation合成は「ギザギザ」にならず綺麗に処理されるようです。
コンテナなどのキャッシュをも利用できますので、方法によっては応用性に富むと思われます。


テキストを横に配置する単純な形、(伸縮回転なし)

▲[ 目次 ]


テキストを横に配置するだけですが、右位置、中央補正の指定は出来ます。伸縮回転なしの簡単な作りです。
そのために、合成の種類を問いません。但し旨く合成なるかは別問題です。



var text_pos=0;//右位置
var center=false;//中央補正

//汎用処理用1/スペース設定はない
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、中央補正
function composite_canvas(w,h,c,font,fsize,fcolor,text,img,composite,text_pos,center) {

	var align="left";
	if(center) {align="center";text_pos=w/2;}

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(img,0,0,w,h);
	//TEXT
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign=align;
	ctx.textBaseline="middle";
	ctx.globalCompositeOperation=composite;
	//Text
	ctx.fillText(text,text_pos,h/2);

	return canvas;
}

中央固定形、(未使用)

▲[ 目次 ]


簡単にできています、常に中央に配置する場合は便利です。これは未使用です。




//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類
maskText2=new createjs.Bitmap(composite_canvas2(640,100,"#CCCCCC"....."destination-in"));

//汎用処理用2/中央専用
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類
function composite_canvas2(w,h,c,font,fsize,fcolor,text,img,composite) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(img,0,0,w,h);
	//TEXT
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	ctx.globalCompositeOperation=composite;
	//Text
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

テキストを分解横に配置形、(伸縮回転なし)

▲[ 目次 ]


テキストを分解していますので、文字間の間隔を調整可能です。
合成は原則、「destination-out」ですが、composite種類を指定できますが、この場合ブラウザの確認が必要です。
「デモ」サンプル1、


引数、center がtrue の場合は中央補正されます。「destination-in」は指定できません。

分解文字毎に「destination-in」合成をするので、重なり順が変わり、前の文字が消えてしまうのが原因です。
複数文字を1枚の画像に変換すれば、この問題は解決されます。下の別項「特殊処理形」になります。




	//文字分解し再配置
	var text_pos=100;//右位置
	var text_spc=-2;//テキストスペース、重なり注意
	var center=true;//中央補正

	//destination-in/destination-out/xor以外は効果なし
	//TESTコンテナ1
	maskcontainer.x=0;
	maskcontainer.y=0;
	var img=assets[0];
	//destination-outとxorのみ
	//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、スペース、中央補正
	maskText=new createjs.Bitmap(composite_text(640,100,"#CCCCCC","Impact","65px","#FF0000","POPS WEB KOUBOU",img,"destination-out",text_pos,text_spc,true));
	maskcontainer.addChild(maskText);



//汎用処理用分解配置
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、右位置、スペース、中央補正
function composite_text(w,h,c,font,fsize,fcolor,text,img,composite,text_pos,space,center) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(img,0,0,w,h);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	var tpos_x=text_pos;//右位置
	var tpos_y=h/2;

	//中央補正
	if(center) {
		var alltext_width=0;
		ctx.font=font_v;
		var alltext_width=ctx.measureText(text).width+(text.length-1)*space;//全幅取得暫定計算
		ctx.fillText("",0,0);
		//ほぼ中央
		tpos_x=(w-alltext_width)/2;
	}

	//分解配置
	for (var i=0; i < text.length; i++) {

		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		var tx=text.charAt(i);
		var fw=ctx.measureText(tx).width;//幅取得
		//X位置
		tpos_x +=fw/2;

		//Text描画
		ctx.globalCompositeOperation=composite;
		ctx.fillText(tx,tpos_x,tpos_y);

		//位置加算
		tpos_x +=fw/2+space;//half+space
	}

	return canvas;
}

文字伸縮回転形、(文字分解なし)

▲[ 目次 ]


 

文字伸縮回転できますが、文字の間隔の調整は出来ません。文字は中央配置になります。
合成は原則、「destination-out」「destination-in」です。composite種類を指定できますが、この場合ブラウザの確認が必要です。
「デモ」サンプル4、




//文字回転形分解なし中央補正
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、拡大、角度
function composite_canvas_S(w,h,c,font,fsize,fcolor,text,img,composite,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);
	//背景
	ctx.drawImage(img,-w/2,-h/2,w,h);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;

	ctx.scale(scale,scale);
	ctx.rotate(angle);

	//TEXT描画
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	ctx.globalCompositeOperation=composite;
	//Text
	ctx.fillText(text,0,0);

	return canvas;
}

文字伸縮回転形、(文字分解)

▲[ 目次 ]


 

文字伸縮回転でき、文字の間隔の調整も行えます。文字は中央配置になります。
合成は原則、「destination-out」です。composite種類を指定できますが、この場合ブラウザの確認が必要です。
陰影は逆方向に処理されますので注意ください。ステージ背景は文字で抜かれる。


注意、文字分解形に「destination-in」を指定すれば文字の部分がなくなります。


「destination-out」と「xor」は似通っています。
「デモ」サンプル5、




//文字回転形分解配置原点中央のみ
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、スペース、拡大、角度
function composite_text_S(w,h,c,font,fsize,fcolor,text,img,composite,space,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);
	//背景
	ctx.drawImage(img,-w/2,-h/2,w,h);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	var tpos_x=0;//中央位置
	var tpos_y=h/2;

	//強制中央補正
	var alltext_width=0;
	ctx.font=font_v;
	var alltext_width=ctx.measureText(text).width+(text.length-1)*space;//全幅取得暫定計算
	ctx.fillText("",0,0);//幅取だけなので描画しなくとも良い
	//ほぼ中央の補正値
	pos_v=alltext_width/2;

	ctx.scale(scale,scale);
	ctx.rotate(angle);

	//分解配置
	for (var i=0; i < text.length; i++) {

		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		var tx=text.charAt(i);
		var fw=ctx.measureText(tx).width;//幅取得
		//X位置
		tpos_x +=fw/2;

		//Text描画
		ctx.globalCompositeOperation=composite;
		ctx.fillText(tx,tpos_x-pos_v,0);//X補正

		//位置加算
		tpos_x +=fw/2+space;//half+space
	}

	return canvas;
}

特殊処理形、(文字分解画像化)

▲[ 目次 ]


 

上の、文字分解したものは文字間隔などを調整出来るために便利であるが、処理の都合上「destination-in」を指定すれば文字の部分がなくなります。どうしても「destination-in」が必要な訳ではありませんが、.....
そこで、分解文字を配置したものを、一括して画像化して1枚の画像にすることにより「destination-in」を指定出来るようにした。途中で画像化したテキストを取得している。


TextにshadowBlur処理しますと、合成境界がよりボケます。この場合にBitmapに陰影処理すれば、Chromeでの陰影が可能と成ります。(不思議だが、ここは不具合解決の糸口になるカモ)
但し、合成の種類により多少の見た目の相違はありますが、あまり気が付くものではない。Chromeの方は「デモ」で実行出来ます。
一般的にChromeで、画像透過部分と画像の境目に陰影が付かないのは、Chromeで画像処理(PNG32)が違っているのに起因していると思うのですが.........


「デモ」サンプル6、




//文字分解し再配置/原点中央補正のみ
var text_spc=-10;//テキストスペース、重なりOK
var img=backphotos[0];
var scale=2;//拡大
var angle=Math.PI/12;//角度

//destination-in/destination-out
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、スペース、拡大、角度
maskText4=new createjs.Bitmap(composite_canvas_W(640,300,"#CCCCCC","Impact","60px","#FF0000","POPS WEB KOUBOU",img,"destination-in",text_spc,scale,angle));

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

//特殊
//文字回転形分解配置原点中央のみ/画像で合成
//幅、高さ、色、文字種、サイズ、文字色、画像、ストリング、composite種類、スペース、拡大、角度
function composite_canvas_W(w,h,c,font,fsize,fcolor,text,img,composite,space,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);
	//背景
	ctx.drawImage(img,-w/2,-h/2,w,h);
	//Text画像描画取得
	var image=textCanvas_W(w,h,c,font,fsize,fcolor,text,space,scale,angle);
	ctx.globalCompositeOperation=composite;
	//合成
	ctx.drawImage(image,-w/2,-h/2,w,h);

	return canvas;
}
//幅、高さ、色、文字種、サイズ、文字色、ストリング、スペース、拡大、角度
function textCanvas_W(w,h,c,font,fsize,fcolor,text,space,scale,angle) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//原点移動translate
	ctx.translate(w/2,h/2);

	//TEXT設定
	var font_v=fsize +" "+ font;
	ctx.fillStyle=fcolor;
	var tpos_x=0;//中央位置
	var tpos_y=h/2;

	//強制中央補正
	var alltext_width=0;
	ctx.font=font_v;
	var alltext_width=ctx.measureText(text).width+(text.length-1)*space;//全幅取得暫定計算
	ctx.fillText("",0,0);
	//ほぼ中央の補正値
	pos_v=alltext_width/2;

	ctx.scale(scale,scale);
	ctx.rotate(angle);

	//set_shadow (ctx,"#FFFFFF");//ぼかすとChromeでの陰影が可能だ

	//分解配置
	for (var i=0; i < text.length; i++) {

		ctx.font=font_v;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		var tx=text.charAt(i);
		var fw=ctx.measureText(tx).width;//幅取得
		//X位置
		tpos_x +=fw/2;

		//Text描画
		ctx.fillText(tx,tpos_x-pos_v,0);//X補正

		//位置加算
		tpos_x +=fw/2+space;//half+space
	}

	return canvas;
}

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

//Textに陰影BlurRGB変換なし
function set_shadow (ctx,color) {

	ctx.shadowColor=color;//OK
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=5;//3-5
}

 

その他

▲[ 目次 ]


トリミング

大きな画像の場合はトリミングが必要に成る場合もあるでしょう。下記の、imageTrimmingCanvas関数を利用すればトリミングできます。drawImage()処理。
指定は画像範囲内で行ってください。下記例 のbackphotos[2] は読み込み画像のresult値です。



トリミング画像=imageTrimmingCanvas(画像,元画像X,元画像Y,元画像W,元画像H,0,0,新画像W,新画像H);

//トリミング画像、X、Y、幅、高さ、
var img=imageTrimmingCanvas(backphotos[2],0,100,640,100,0,0,640,100);

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

//トリミング画像、X、Y、幅、高さ、
function imageTrimmingCanvas(patternimg,sx,sy,sw,sh,dx,dy,dw,dh) {
	//Box
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=sw;
	canvas.height=sh;
	var ctx=canvas.getContext("2d");
	ctx.drawImage(patternimg,sx,sy,sw,sh,dx,dy,dw,dh);

	return canvas;
}

代替画像の使用

テキストで抜く場合などでは、画像ではなくグラデーション塗りのエレメント、またはベタ塗りのエレメントがほしい場合があります。画像で作るには大変面倒です。
次の様にして簡単に作ることが出来ます。画像の代わりに入れればよい。


● ベタ塗りのエレメント
読み込み画像の変わりに「色つきのエレメント」を作り代入すればよい。



赤色ベタぬり
var img=createColorCanvas(640,100,"#FF0000");
赤色ベタぬり、透明度0.5
var img=createColorCanvas(640,100,"rgba(255,0,0,0.5)");

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

//色画像
//全幅、全高さ、背景色
function createColorCanvas(w,h,c) {
	//Box
	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;
}


● グラデーション塗りのエレメント(ライングラデーション)
読み込み画像の変わりに「グラデーション塗りのエレメント」を作り代入すればよい。
LinearGradientの例、二番目は画像と同じものを「エレメント」で作れる。色、direction、type、の設定で色々な形態になる。透明度は、rgba() で指定できる。



1、上赤色、下白色のY方向ライングラデーション
var img=createLineGradBox(640,100,"#FF0000","#FFFFFF","#FF0000","y",2);

2、上黒色透明度0、下黒色透明度1のY方向ライングラデーション
var img=createLineGradBox(640,100,"rgba(0,0,0,0)","rgba(0,0,0,1)","rgba(0,0,0,0)","y",2);

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

//LinearGradientBox
//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
function createLineGradBox (w,h,color1,color2,color3,direction,type) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");

	//LinearGradient
	var gradient;
	if(direction == 'x') {
		gradient=ctx.createLinearGradient(0,h,w,h);
	}
	if(direction == 'y') {
		gradient=ctx.createLinearGradient(w,0,w,h);
	}
	if(direction == 'xy') {
		gradient=ctx.createLinearGradient(0,0,w,h);
	}
	if(type == 2) {
		gradient.addColorStop(0,color1);
		gradient.addColorStop(1,color2);
	}
	if(type == 3) {
		gradient.addColorStop(0,color1);
		gradient.addColorStop(0.5,color2);
		gradient.addColorStop(1,color3);
	}
	ctx.fillStyle=gradient;
	//FILL
	ctx.fillRect(0,0,w,h);

	return canvas;
}

陰影処理

陰影処理はBitmapインスタンス側に処理すれば、テキスト部分に陰影処理されますが、合成の種類によって形態が違ってきます。状況によっては必要な場合もあるでしょう。
また予期せぬ部分に陰影処理される場合もありますので、確認ください。
尚、Chromeでは綺麗に陰影処理されませんのでご了承ください。(付ける方法はあるようだ)

「デモ」の様にText処理の場合のみのようです。「PNG画像を読み込み」テストしてみましたが通常の透過画像では「Chromeで陰影を付ける」ことは出来ませんでした。2014/10/01追記


テキスト以外での処理

「デモ」などでは、画像とテキストを対象に処理していますが、別に他が対象でもよろしい訳です。「Canvasエレメント」を表示の際にBitmapクラスに収容すればよい。
画像なら、ctx.drawImage() で描画できる、fillStyle指定でも描画可能です。
また、コンテナのキャッシュも利用できる。(キャッシュは画像同様です)




インスタンス=new createjs.Bitmap(hogeHage(横幅,高さ,......));

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

//処理関数
function hogeHage(w,h,......) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//背景
	ctx.drawImage(画像など,0,0,w,h);

	//対象エレメントの合成指定
	ctx.globalCompositeOperation=合成の種類;
	//対象エレメントの処理
	ctx...............

	return canvas;
}

画像

原則、使用者が用意ください。640x100画像、640x300画像、デモ使用の画像は「デモページ」にあります。


テキストマスクのためにフォントをGraphicsクラスで描画する方法。少し面倒ですが!

【参照】当方の記事: CreateJS フォントをGraphicsクラスで描画する



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

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


 

以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]