POPSブログ

CreateJS Canvasエレメント描画のOutlineテキストをBitmapクラスで表示する

284

  Category:  javascript2014/03/14 pops 

CreateJS Textクラスでの「文字の装飾」は現在単に表示する程度で完全ではない。CanvasエレメントにHTML5 Canvas仕様で描画したものを、Bitmapクラスで表示する事により「文字の装飾」が多彩に成る。
勿論、通常の画像もラインの染めの部材に利用できます。Outlineテキストでのテストを行います。
easeljs-0.7 でのテストです。

 

CreateJS Canvas Outlineテキスト 表示テスト


グラデーション処理のCanvas要素に陰影処理をした場合に、Safariで陰影を表示しない不具合が有りますのでこれを修正します。当方、MAC用 Safari6 7 での確認が出来ませんので、一応、不具合があるとみなし補正処理をします。


Html5 Canvasエレメント描画に関連する事なので多少繁雑です。興味のある方のみお読み下さい。

簡単な説明目次に進む


下図の様に、画像ではあるがFontに画像を塗りこみ「装飾文字」表示が可能となる。CreateJSのTextクラス機能が充実されるまで代替として利用できるので、詰まんなかった文字周りがキレイになります。
少し事件はおきますが、ゴマカシます。


 

DEMO


CreateJS Canvas Outlineテキスト テスト、(createJS069.js)

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



Chrome Firefox Safari(Win) Opera 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-0.5.0.min.jsは不要です。


HTML (HTML5)


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

JS

createJS069.js、JS名は任意に変更可。注意、easeljs-0.7用です。
デモのシミュレーション部分はカットしていますので同一では有りません。


//日本語
//createJS069.js
//Canvasテキストアウトライン用Safari陰影修正済み
//easeljs-0.7用

//canvasの大きさ
var canvasWidth=640;
var canvasHeight=300;

//文字BOXの大きさ
var logoBoxWidth=600;
var logoBoxHeight=60;

//説明TEXT
var textUse=true;

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

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

//ステージ
var stage;
//コンテナ
var logoContainer;

//画像 Bitmapインスタンス
var welcomeImage;
var logoImage,logoImage2,logoImage3;

//説明TEXTインスタンス
var viewtext;

//画像保存容器
var assets=[];

//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("#FFFFFF").drawRect(0,0,canvasWidth,canvasHeight);
	stage.addChild(backrect);

	//welcome画像層画像表示
	welcomeImage=new createjs.Bitmap("/main/images/lady_back2.png");
	stage.addChild(welcomeImage);
	//表示
	welcomeImage.visible=true;

	//画像埋め込みLOGO
	logoContainer=new createjs.Container();
	//1
	logoImage=new createjs.Bitmap();
	logoImage.x=(canvasWidth-logoBoxWidth)/2;
	logoImage.y=110;
	//2
	logoImage2=new createjs.Bitmap();
	logoImage2.x=(canvasWidth-logoBoxWidth)/2;
	logoImage2.y=175;
	//3
	logoImage3=new createjs.Bitmap();
	logoImage3.x=(canvasWidth-logoBoxWidth)/2;
	logoImage3.y=220;
	logoContainer.addChild(logoImage,logoImage2,logoImage3);
	stage.addChild(logoContainer);

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

			//表示に進む
			draw();

		},1000);
	}
}

//DRAW
function draw() {

	var font_name="Arial";
	var font_name2="Impact";
	var font_name3="Serif";//IE9で文字が若干大きくなる
	//var img=null;

	//-----------------1
	var img=assets[0];
	//Logoアウトライン専用
	//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影、パタン画像、ストリング
	var logo=createTextOutlineLogo (logoBoxWidth,logoBoxHeight,"rgba(0,0,0,0)",font_name,"bold 46px","#FFFFFF","#FFFFFF",3,true,"#000000",true,img,'POPS WEB KOUBOU');
	logoImage.image=new createjs.Bitmap(logo).image;

	//-----------------2
	//IE9で画像がズレる、Fontによってはズレない
	var img=assets[2];

	//パターン挿入例1
	//var img=createPatternCanvas5(10,10,"#CCCCCC","#FFFFFF");
	//パターン挿入例2
	//var img=createPatternCanvas4(100,65,"#228B22","#FF0000");

	var logo=createTextStandard2 (logoBoxWidth,logoBoxHeight,"rgba(0,0,0,0)",font_name2,"bold 46px","#FF0000",true,img,'WELCOME');
	logoImage2.image=new createjs.Bitmap(logo).image;

	//-----------------3
	var img=assets[1];
	//幅、高さ、色、文字種、サイズ、文字色、陰影、パタン画像、ストリング
	var logo=createTextStandard2 (logoBoxWidth,logoBoxHeight,"rgba(0,0,0,0)",font_name3,"bold 40px","#FF69B4",true,img,'Web Design & Jyoudan!');
	logoImage3.image=new createjs.Bitmap(logo).image;

}

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

//VIEWTEXT
function set_text(t) {

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

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

//標準
//幅、高さ、色、文字種、サイズ、文字色、陰影、パタン画像、ストリング
function createTextStandard (w,h,c,font,fsize,fcolor,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;

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

	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (shadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

//標準/Safari補正済
//幅、高さ、色、文字種、サイズ、文字色、陰影、パタン画像、ストリング
function createTextStandard2 (w,h,c,font,fsize,fcolor,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";

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

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

	//Text
	if (shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

//LOGO-Canvasテキストアウトライン専用/Safari補正済
//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影、パタン画像、ストリング
function createTextOutlineLogo (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補正用下層テキスト、重ね塗り
	if(shadow) {
		ctx.strokeStyle=scolor;
		set_shadow (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
		set_shadow (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
	}

	//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テキストアウトライン専用2/補正必要なし
//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影もどき、パタン画像、ストリング
function createTextOutlineLogo2 (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をずらした陰影もどき
	ctx.strokeStyle=scolor;
	ctx.lineWidth=lwidth;
	ctx.strokeText(text,w/2+2,h/2+2);

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

	//TEXT-LINE
	ctx.lineWidth=lwidth;
	ctx.strokeText(text,w/2,h/2);

	return canvas;
}

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

//上下2色Pattern
function createPatternCanvas4 (w,h,c1,c2) {

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

	ctx.fillStyle=c1;
	ctx.fillRect(0,0,w,h/2);

	ctx.fillStyle=c2;
	ctx.fillRect(0,h/2,w,h/2);

	return canvas;
}
//4角連続Pattern
function createPatternCanvas5 (w,h,c1,c2) {

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

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

	ctx.fillStyle=c2;
	ctx.fillRect(0,0,w*0.8,h*0.8);

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

//Textに陰影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;
}

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

//START
init();

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


CSS

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


/*日本語createJS069.css*/

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

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

#image-box #mainCanvas {
border-radius:10px;
}
canvas {
border-style:none;
background-color:transparent;
}

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

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


簡単な説明


新たに、HTML5 Canvas仕様での記述方法を覚えなければ成りませんがさほど大変では有りません。
テキストで在っても画像としての表示ですが、多用な「文字デザイン」の可能な事が今重要です。


 

[ 簡単な説明の複雑な目次 ]


 

 

 

一行テキストの構造、標準形

▲[ 目次 ]

[説明図]

 

「デモ」での処理関数では、上図の様な構造になりますので、テキストの大きさが必ずしも同じとは限りませんので、
原則、透明 rgba(0,0,0,0) を指定します。テキスト背景色を設定する場合は16進の色(#000000など)を指定します。
殆んどのテキスト「陰影」は、true false で指定出来ます。(作り方次第ですが...)


先に、エレメントの大きさを指定していますので、エレメントとテキストの関係などは上図の様になります。

表示状態を確認しながら、エレメントの大きさ等を調整します。


テキストは通常のグラデーション、画像、Canvasエレメントも塗りの素材として指定できます。グラデーション設定の基準はテキストではなく、外側のctxに成りますので注意下さい。


この辺の詳細説明などは、下記記事を参照下さい。

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


Font名の指定

表示するマシン環境に依存しますので、原則、Font名の指定は難しい。

Fontによっては textBaseline が機能しなかったり、大きさが違ったり、ブラウザにより表示位置Y方向が微妙に違う。「デモ」では Arial、Impact、Serif、を指定してある。(勿論、Font名の指定は保障されるものではない)
Fontを必ず指定したい場合は、WebFontを使用すれば良いと思います。


表示テキスト寸法のエレメントを作る

エレメントを作る際は先に大きさを指定して作りますので、途中でエレメントの大きさの変更は出来ません。
但し、仮にCreateJS「Textクラス」のインスタンスを作り、その寸法を取得する事は可能です。ページ最後に記載しておきます。


▲[ 目次 ]

 

Safari不具合の修正と問題点

▲[ 目次 ]

陰影の部分のテキストを2重にして不具合を防ぐ方法であるが構造によっては、出来ない場合も在るかも知れない。


問題点などもあるので先にこれらを調べた上で、修正の説明をする。


Safari不具合が出るのは、一般的に次ぎの条件の場合である。


1. テキストにグラデーション塗りをする場合。
2. テキストに画像塗り、またはCanvasエレメントで塗る場合(画像と同一)。


[説明図]

 

Safari陰影の不具合はグラデーション塗りの場合のみであり、通常の色を着色している時は発生しない。

よって、次ぎの様にする。


1. 上図の様にグラデーション部材の下に陰影専用のテキスト層を作り重ねる形にした。
2. かならず、Bitmapに収容しますので、Bitmap層に通常のCreateJS陰影処理をしても良いが....
(但し、SafariはOKであるが、Chromeで処理されない場合あり、意図しない部分にも陰影が付く時がある)


問題点としては、


1. ブラウザによっては、上層にも陰影が掛かり、濃くなるのでこれも補正する。
2. 反対に重なり具合では陰影が消えてしまう不可解なことも起こる。
3. ブラウザによって陰影の品質が違うので注意が必要。(Operaが一番キレイだ)
4. MAC用 Safari では未確認である。(ダイジョウブと思うが.......)
5. その他なんか起きたら「未解決事件の迷宮入り」としてシランフリをし、時効を待つ他方法がない。
6. 大変面倒で問題もでるので、Safariを無視するのも選択の1つだ。


テキストのCreateJS「shadowフィルター」陰影処理の振る舞い

元来、CreateJS「shadowフィルター」はCreateJSで作った「インスタンス」に陰影処理する目的のためにある故、
複雑なエレメント構造では必ずしも正確に陰影処理するものではないし、ブラウザによっても差異がある。


ここでは、Canvasエレメント描画テキスト(実態は画像同様)をBitmap()処理する特殊なものであるが、Chrome以外は問題はなさそうである。Chromeでは構造次第で処理されないことがある。


● Bitmap層にCreateJS「shadowフィルター」陰影処理をする

▲[ 目次 ]

Fill描画に白のアウトラインを描画したテキストCanvasエレメントを作り、表示のためBitmapに収容して、
親のBitmapにフィルターをして見る。中のCanvasでshadowBlur陰影は付けていない。
下図の様になる。


 

陰影用の階層を用意して処理するのが面倒な場合は、Safariのみ判別して、通常のCreateJS 「shadowフィルター」処理をしても良い。Safari は正常に陰影処理される。
但し、この構造では Chrome は処理されない。(外のctx背景が原因ではないようだ、不明)


Chromeの CreateJS「shadowフィルター」処理は構造次第では結構不安定である(CreateJSのインスタンス構成の画像挿入ボタンでもそうで在った)。処理して見ないとわからない面がある。



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

● 陰影処理をする所を制御する(shadowBlur陰影)

▲[ 目次 ]

下のテキスト層が通常のテキストの場合(アウトラインではない)

ここでの、Canvasエレメントで塗る場合に限りではあるが、下のテキストにshadowBlur陰影処理すると「上のアウトライン」にも陰影が付く。チョット汚い....... 但し、構造などにより違いがあるので、確認の上に補正する。


 

Canvas要素は1つでも、複数の部材がありますので、ブラウザによりけりですが、最下位層に陰影処理をすると上の層にも陰影が掛かる時が有ります。


Canvasの、shadow処理をするはあっても、shadowを削除するは見当たらない。


ctxは1つですので仕方がない。但し次のようにすると上層の陰影が防げます。



//消す
if (shadow) {ctx.shadowColor="rgba(0,0,0,0)";}

● アウトラインテキストは陰影が薄い

▲[ 目次 ]

アウトラインで描画すると、線が細いため陰影が薄くなります。太いとアウトラインの意味がないのでこの辺は適当に。
Chromeは特に描画品質良くないので、最低 2-3ピクセル幅 がほしい所だ。

 

下のテキスト層がアウトラインテキストの場合

Safari対策のために、下層に陰影用のテキスト層をいれています。陰影が薄くとも上の層(グラデーション処理層と同じ)でSafariは調整は出来ません。(Safari以外ならどのようにでも調整できる)
その為に、下層に2回の陰影処理をし陰影を濃くしている (つまりは3層構造になります)。上層の影響を抑えるために上層では影を透明にする。ブラウザ毎確認しながらの作業ゆえ結構面倒である。



//Safari補正用下層テキスト、重ね塗り
if(shadow) {
	ctx.strokeStyle=scolor;
	set_shadow (ctx,scolor);
	ctx.strokeText(text,w/2,h/2);
	set_shadow (ctx,scolor);
	ctx.strokeText(text,w/2,h/2);
}

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

shadowOffsetX Yが0なら、以下でも消すこと出来ます。つまりテキストの下に隠れる。


//陰影を消す
if(shadow) {ctx.shadowBlur=0;}

上層で調整は可能だが、グラデーション層で在るゆえにSafariでは陰影が処理されなくなる。
下層の薄い影に上層で濃い影を重ねることになる。つまりは工夫する。


//Blur0-1で濃くなるよう調整は可能ですが...
if(shadow) {ctx.shadowBlur=1;}

● 影で影が隠れてしまうハプニング

▲[ 目次 ]

下の図は「3D風テキスト」の感じを出したもので、今回は画像のみである。
左から右下方に向かって描画すると、描いたものが消えたりと色々とハプニングが起きる。陰影付きなら尚更変になる。影に影が隠れて何も表示しないとか「ワカラン」現象が起こるそうだ。
Canvasエレメント描画重ね順は指定できないので描いた順で有り、陰影はおそらくPaddingで処理されていると思うので、これらの影響で思い通り行かないのであろう。


 

ちなみに、上の「3D風テキスト」は右下より順に重ねて描いている。次回に登場します(今日は予告編になります)。

 

 

以上、まとめてみると....


1. Safari の補正は、CreateJS「shadowフィルター」処理でも解決する。
2. Chrome の画像に対する、CreateJS「shadowフィルター」処理は不安定。
3. アウトラインテキストの shadowBlurに拠るshadow処理 は薄く効果が少ない。
(今回は影2枚で濃くした、色々方法は有ると思ひます)
4. shadowBlur処理は意図しない所にも陰影を付けてしまうので修正が大変だ。
5. ハプニングは別冊付録だ。骨折しない程度にアタマをひねろう。


 

/// 上記の特性を踏まえて、Safari不具合の修正をしてみる。///

 

Safari不具合の実際の修正処理

▲[ 目次 ]

未処理の場合と、Safari不具合修正、の2通りを以下に示す。アウトライン用は最後に記す。

現在、Safariのシェアは極わずかであるから、ワタシは無視しても良いと考えている。


アウトライン以外のもの

▲[ 目次 ]

● 修正処理のない形式、簡単で良い。(Safariで陰影が付かない)

Safariのみ、CreateJS「shadowフィルター」処理すれば品質はどうあれ修正は可能。



//標準
//幅、高さ、色、文字種、サイズ、文字色、陰影、パタン画像、ストリング
function createTextStandard (w,h,c,font,fsize,fcolor,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;

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

	ctx.font=font_v;
	ctx.textAlign="center";
	ctx.textBaseline="middle";
	//Textに陰影
	if (shadow) {set_shadow (ctx,"#000000");}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

エレメントの背景であるが必ずしも必要ではないので削除は可能である。


	略す

	var ctx=canvas.getContext("2d");
	ctx.fillStyle=c;
	ctx.fillRect(0,0,w,h);

	略す

● 処理のなされている形式、些か面倒ではある。(上記のJSを修正したもの)
何とか、不具合関連はこれで解消し、殆んどのブラウザでも問題は起きないと思われます。


IE9で少し問題に成る部分あり、IE9で描写画像が小さいので下の色が食み出す、参照下さい



//標準/Safari補正済
//幅、高さ、色、文字種、サイズ、文字色、陰影、パタン画像、ストリング
function createTextStandard2 (w,h,c,font,fsize,fcolor,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";

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

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

	//Text
	if (shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
	ctx.fillText(text,w/2,h/2);

	return canvas;
}

実際の CreateJS「shadowフィルター」陰影処理


Safariで、グラデーション塗りなどのCanvas要素で陰影処理が効かない不具合が有る。

CreateJS「shadowフィルター」処理すれば良いが、Chromeで処理されない事もあるので、原則、CanvasのshadowBlur陰影処理はしておくべきで、「shadowフィルター」は最終手段である。


 

陰影処理の必要な場合に、
Safariを判定して、Canvas要素の入った「Bitmapインスタンス」にCreateJS「shadowフィルター」する

Safariで陰影品質は良いが、構造次第ではどうなるかわからないので確認が必要。



Browser判定する
//------------------------------------------------------
//Browser判定
var userAgent = window.navigator.userAgent.toLowerCase();
var safari=false;
if (userAgent.indexOf("safari") > -1) {safari=true;}
//------------------------------------------------------

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

Bitmapインスタンスにshadowフィルター

var logo=createTextStandard (..........);
logoImage.image=new createjs.Bitmap(logo).image;

対象のBitmapインスタンス
if(safari) {
	logoImage.shadow=shadow;
}

古いSafari(WIN)では一応陰影処理されます。


アウトライン用

▲[ 目次 ]

以下は、アウトライン用にSafari補正したものである。
「デモ」では Arial で描かれた一番上のテキストである。 SafariでOKですし、殆んどのブラウザでも問題は起きないと思われます。確認しながら旨く重ねてゆくのがコツのようです。

アウトライン以外のものとは区別してください。


アウトラインの幅は最低 2ピクセル を設定下さい。1ピクセルでも可能ですがChromeで大変見苦しいのが理由です。



//LOGO-Canvasテキストアウトライン専用/Safari補正済
//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影、パタン画像、ストリング
function createTextOutlineLogo (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補正用下層テキスト、重ね塗り
	if(shadow) {
		ctx.strokeStyle=scolor;
		set_shadow (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
		set_shadow (ctx,scolor);
		ctx.strokeText(text,w/2,h/2);
	}

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

アウトライン用陰影もどき (陰影処理無し)

▲[ 目次 ]

アウトライン用ですが、陰影はグラデーション状では無く、黒のアウトラインテキストを少しずらして配置しています。
shadowBlur陰影で有りませんので当然Safariで問題は出ません。但しChromeでキレイにナラ無いのが欠点です。

ここでは2ピクセル右下方にずらしています。


Safariの不具合がなければ、陰影をずらすだけで簡単なのですが....



//LOGO-Canvasテキストアウトライン専用2/補正必要なし
//幅、高さ、色、文字種、サイズ、文字色、ライン色、ライン幅、ライン、陰影色、陰影もどき、パタン画像、ストリング
function createTextOutlineLogo2 (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をずらした陰影もどき
	ctx.strokeStyle=scolor;
	ctx.lineWidth=lwidth;
	ctx.strokeText(text,w/2+2,h/2+2);

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

	//TEXT-LINE
	ctx.lineWidth=lwidth;
	ctx.strokeText(text,w/2,h/2);

	return canvas;
}

Canvas陰影処理、2つ関数

RGB形式での指定なので大変面倒であるゆえに...

Canvas陰影処理に関しては、通常の16進カラーで指定できるように、次ぎの2つ関数を介している。
現在、Offset値は 0 ですが自由に変更出来ます。


//Textに陰影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;
}

toRgb関数がダサイ、何とかならんものでしょうか?


IE9で描写画像が小さいので下の色が食み出す

▲[ 目次 ]

IE9でテキストを画像で染め上げる場合に正確に位置を合わせることが出来ないようです。
テキストの色が出てしまい表示状態が悪い。Fontの種類、大きさによって差があるようですが、見えない場合も有りますのでその時の気分のようです。
IEは何があっても不思議ではないのは「縄文人」でも知ってる一般常識です。


画像指定なき場合のテキスト色が下に見えてしまう。ここでは「赤」。

 

対象、createTextStandard2()で処理した場合


● 対策1、createTextStandard2()の一部を修正する方法。

以下の様に修正する、影の色と同じにしてごまかす。


createTextStandard2()関数

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

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

色を黒にする

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

● 対策2、createTextStandard()を使用する方法。

Safari修正形式でないので、「実際の CreateJS shadowフィルター 陰影処理」を実行する。


● 対策3、許容範囲内として、何もしないでほっとく。

デモでは赤色だから気になるが暗い色なら判らない。Fontによっては起きないこともある


 

テキストを染める部材

▲[ 目次 ]

原則、テキストを画像で染めるのが目的ですが、Canvasエレメントで染めることも出来ます。


テキストを画像などで染める専用です

テキストを画像(またはCanvasエレメント)などで染める専用ですから、画像を使用しない場合はテキストが2重に重なっていますので非効率です。


1. Safari補正をしていますので、面倒な作りになっています。
2. 通常のグラフイックを描く場合は、グラフイックを描いたCanvasエレメントを入れます。
3. グラデーションのデータを引数にする事も可能と思うがここでは省略します。
4. 画像と同様ですので、中の文字個別にアニメなどは出来ません。あくまでも1枚のBitmapとして扱います。


画像の代わりにパターンで染める

グラフイックなどを描いた、Canvasエレメントを作り画像の代わりに使用します。Canvasエレメントは画像と同様です。
アウトライン用には余り合いませんが、テキスト全体を染める場合は大変有効な手段になりますし、Font幅が太いほど良いと思います。
これらは、目的に合わせて自作する事になりますが、結構大変な作業になります。
色、大きさなど簡単に変更できるのが特徴ですので、画像と旨く使い分けるのも有効な手段になります。


「デモ」2番目の所に未使用ですが、記載しています。下記の様にすれば「4角連続Pattern」で染まります。
パターン挿入例2の様に上下分割の場合はブラウザにより文字の高さが変化しますので、完全に合わせることは出来ません。其れなりの表示になります。


グラデーションパターンは作るのが面倒です、次回にします。(ページ更新のためネタは後回し)



//var img=assets[2];

//パターン挿入例1
var img=createPatternCanvas5(10,10,"#CCCCCC","#FFFFFF");
//パターン挿入例2
//var img=createPatternCanvas4(100,65,"#228B22","#FF0000");

//幅、高さ、色、文字種、サイズ、文字色、陰影、パタン画像、ストリング
var logo=createTextStandard2 (logoBoxWidth,logoBoxHeight,.....................);

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

//上下2色Pattern
function createPatternCanvas4 (w,h,c1,c2) {

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

	ctx.fillStyle=c1;
	ctx.fillRect(0,0,w,h/2);

	ctx.fillStyle=c2;
	ctx.fillRect(0,h/2,w,h/2);

	return canvas;
}
//4角連続Pattern
function createPatternCanvas5 (w,h,c1,c2) {

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

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

	ctx.fillStyle=c2;
	ctx.fillRect(0,0,w*0.8,h*0.8);

	return canvas;
}

表示テキストの大きさのエレメントを作る

▲[ 目次 ]

表示テキストのCSS条件で、仮にCreateJS「Textクラス」のインスタンスを作り、その寸法を取得する事で可能です。
エレメントより食み出し部分は表示しませんので、陰影などを考慮した大きさにしてエレメントを作ります。

正確な値を取得出来なくなりますので、textAlign textBaseline などは指定しないで下さい。


下図は、大きさを取得後、その大きさで textBaseline middle を設定して表示したサンプルです。

 

利点として、テキスト塗りの画像、パターンなどの位置を合わせ易く成る。


FontをArialにして表示した例ですが、Firefoxが一番ずれますので注意が必要です。但し漢字(Arialのままで)を表示した時はまた違ってきます。textBaseline:middle も一番表示誤差が少ないようです。
一番誤差が大きくなるのは、「ゴシック」等指定した場合ですので、Arialが一番無難なFont指定と思います。


● getMeasuredWidth Heightで計算して取得


//TEXTの大きさ計算1
var textData=getTextWH(font_name,"bold 46px","POPS WEB KOUBOU");
var logo=createTextOutlineLogo (textData.width,textData.height,............);

//TEXTの大きさGET
function getTextWH(font,fsize,string) {
	var font_v=fsize +" "+ font;
	var text=new createjs.Text(string,font_v);
	var w=text.getMeasuredWidth();
	var h=text.getMeasuredHeight();
	var textData={width:w,height:h};
	return textData;
}

● getBounds()で計算して取得


//TEXTの大きさ計算2
var bounds=getTextWH(font_name,"bold 46px","POPS WEB KOUBOU");
var logo=createTextOutlineLogo (bounds.width,bounds.height,.............);

//TEXTの大きさbounds
function getTextWH(font,fsize,string) {
	var font_v=fsize +" "+ font;
	var text=new createjs.Text(string,font_v);
	var bounds=text.getBounds();
	return bounds;
}

その他

▲[ 目次 ]

Flashではない

Flashは1つのFlashPlayerが対象であるが、JS処理では複数のブラウザが対象であり、それぞれ違いが有る。

特にテキスト周りは違いが多い。よって当分はゴマカシで乗り切るしか手立てはない。疲れる!


使用画像

原則、画像などは使用者がご用意ください。
テキスト背景用(埋め込み)画像、640x100、デモページに表示しています。必要な場合大きさは自由。
イイカゲン適当に作ったほうが効果がある、特にグラデーション系がキレイだ。


▲[ 目次 ]


 

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


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

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


沢山ゴマカシテ、何とか一件落着、以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]