POPSブログ

CreateJS canvgでSVGをラスター画像に変換してBitmap表示

321

  Category:  javascript2014/09/02 pops 

CreateJSで、直接SVGを表示することは可能ですが、canvg.jsを使用して一旦SVGをラスター画像に変換してCreateJSのBitmapクラスで表示して見ます。ChromeでBitmapクラスでの陰影処理に不具合がありますがその修正も考慮してみます。
easeljs-0.7.1 でのテストです。

 

CreateJS canvgでSVGをラスター画像に変換してBitmap表示テスト

今回はInkscapeで作ったSVGをラスター画像に変換して表示します。
ブラウザも多いと、一筋縄ではいかないようですから、ここはChromeを「お縄」にして江戸町奉行所にショッピィて悪人共を「矯正」します。


 

DEMO


CreateJS canvgでSVGをラスター画像に変換してBitmap表示デモ (createJS104.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>
<script type="text/javascript" src="js/tweenjs-0.5.1.min.js"></script>

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


canvg.jsの読み込み

canvg.googlecode.com を利用の場合


<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.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

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

今回はSVGなどを適当に作ってテストしたほうが良いと思います。一応以下デモのJSです...



//日本語
//createJS104.js
//SVG表示canvg変換テスト
//easeljs-0.7.1用

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

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

//ロゴテキスト
var logostring="ポップスウェブ工房";

//画像manifestリスト
var manifest=[
{src:"/main/images/textback03.jpg",id:"text"},
{src:"/main/images/textback01.jpg",id:"text"},
{src:"/main/images/textback10.png",id:"text"},
{src:"/main/xml/test-svg01.svg",id:"svg"},
{src:"/main/xml/test-svg02.svg",id:"svg"},
{src:"/main/xml/test-svg03.svg",id:"svg"}
];

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

//ステージ
var stage;
//コンテナなど
var backrect;
//TEXT
var viewtext;

//LOGO-TEXT
var logotextcontainer;
var logotext;
//MOVE-TEXT
var textChip=[];
var textPosx=[];
var textPosy=[];

//読み込み画像URL保存容器
var assets=[];
var loader;
var image_max;

//SVG
var svgfiles=[];
var svgcontainer;
var svgcontainer2;
var svgcontainer3;
var svgImage;
var svgImage2;
var svgImage3;

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

var backchg_no=0;
var backcolors=["#EEEEEE","#FFFFFF","#BC8F8F","#4682B4","#6B8E23","#FFE4B5","#888888","#333333","#000000"];

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

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

	//STAGE
	stage=new createjs.Stage('mainCanvas');
	//MouseOver重要
	stage.enableMouseOver(20);

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

	//クリック
	backrect.addEventListener("click",backchg);
	stage.addChild(backrect);

	//svg3
	svgcontainer3=new createjs.Container();
	stage.addChild(svgcontainer3);

	//svg2
	svgcontainer2=new createjs.Container();
	stage.addChild(svgcontainer2);

	//svg1
	svgcontainer=new createjs.Container();
	stage.addChild(svgcontainer);

	//LOGO-TEXT
	logotextcontainer=new createjs.Container();
	//表示位置
	logotextcontainer.x=55;
	logotextcontainer.y=200;
	stage.addChild(logotextcontainer);

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

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

}

//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);
	}
	var src=event.item.src;
	if (id == 'svg') {
		//src値
		svgfiles.push(src);
	}
}
//全ての画像読み込み完了
function complete (event) {

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

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

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

			set_text("");
			
			//プロローグ表示に進む
			set_prologue();

		},1000);
	}

}

//背景色変更
function backchg() {
	backchg_no ++;
	if (backchg_no > backcolors.length-1) {backchg_no=0;}
	var color=backcolors[backchg_no];
	backrect.graphics.beginFill(color).drawRect(0,0,canvasWidth,canvasHeight);
}

//プロローグ
function set_prologue() {

	//個別にVSG描画
	svgImage3=new createjs.Bitmap(canvgCanvas(canvasWidth,canvasHeight,svgfiles[2]));//canvg
	svgImage3.shadow=shadow;
	svgcontainer3.addChild(svgImage3);

	svgImage2=new createjs.Bitmap(canvgCanvas(canvasWidth,canvasHeight,svgfiles[1]));//canvg
	svgImage2.shadow=shadow;
	svgcontainer2.addChild(svgImage2);

	//通常の処理/陰影はBitmapで
	//svgImage=new createjs.Bitmap(canvgCanvas(canvasWidth,canvasHeight,svgfiles[0]));//canvg
	//Canvas-Shadowの処理
	//幅、高さ、SVG、陰影、陰影色(16進カラー指定)
	svgImage=new createjs.Bitmap(canvgCanvasShadow(canvasWidth,canvasHeight,svgfiles[0],true,"#000000"));//canvg
	//svgImage.shadow=shadow;//現在Canvasで処理
	svgcontainer.addChild(svgImage);

	//FadeIn
	svgImage.alpha=0;
	var twn=createjs.Tween.get(svgImage)
	.wait(500)
	.to({alpha:1},1000)
	.call(function () {
		//
	});

	//調整
	setTimeout(function() {
		//日本語テキスト表示に進む
		set_drawlogo();
	},2000);

}

//日本語テキスト表示
function set_drawlogo() {

	set_text("");

	//LOGOテキスト
	var logotext_W=0;
	var text_spc=-5;//テキストスペース
	var center=true;
	var tcount=0;
	var outline_w=2;//アウトライン幅

	//ベース表示,アウトライン表示,陰影
	var base=true;//ベース表示
	var line=true;//アウトライン表示
	var lcolor="#FFFFFF";//アウトライン色
	var shadow=true;//陰影
	var scolor="#000000";//陰影色
	var imgshadow=false;//画像陰影

	//色替え/アニメで無いため効果なし
	var colorChg=false;
	var colortype="rainbow";//rainbow rondam #FF0000

	//画像
	var img=assets[2];//アルファチャンネル画像
	var img_alpha=1;
	var fcolor="#FFFFFF";

	var font_name="Arial";
	var size="bold 55px";//Arial用

	//インスタンス配列取得
	//CanvasW,H,サイズ,フォント,文字色,ライン色,アウトライン幅,虹色,スペース,陰影色,陰影,画像,画像透明度,文字,base表示,line表示
	textChip=createMoveOutlineTextCanvas_D(100,100,size,font_name,fcolor,lcolor,outline_w,true,text_spc,scolor,shadow,img,img_alpha,imgshadow,logostring,base,line);

	var textlen=logostring.length;

	//配置のため全幅の計算を先に
	for (var i=0; i < textlen; i++) {
		logotext_W +=textChip[i].width;
		if(i < textlen) {logotext_W +=text_spc;}
	}
	//コンテナ中央
	if (center) {logotextcontainer.x=(canvasWidth-logotext_W)/2;}
	//アニメなし表示のみ
	for (var i=0; i < textlen; i++) {
		//addChild
		logotextcontainer.addChild(textChip[i]);
	}

}

//MOVE-画像修飾Outlineテキストインスタンスを作る2
//reg原点中央補正コンテナ収容
//CanvasW,H,サイズ,フォント,文字色,ライン色,アウトライン幅,虹色,スペース,陰影色,陰影,画像,画像透明度,文字,base表示,line表示
function createMoveOutlineTextCanvas_D(CanvasW,CanvasH,size,font,fcolor,lcolor,outline_w,rainbow,space,scolor,shadow,img,imgalpha,imgshadow,str,base,line) {

	var fontdata=size + " " + font;

	var chip=[];
	var len=str.length;
	var tpos_x=0;
	var tpos_y=0;

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

		//1文字
		var text=str.charAt(i);

		//コンテナ
		var contna=new createjs.Container();

		//虹色
		if (rainbow) {
			fcolor=createjs.Graphics.getHSL(i/len*360,100,50);//直接
		}

		//文字インスタンスを作る
		var t=new createjs.Text("",fontdata,fcolor);
		//1文字入れる
		t.text=text;
		t.name="base";
		t.colorno=""+parseInt(i/len*360);//虹色番号文字
		//幅高さ
		var w=t.getMeasuredWidth();
		var h=t.getMeasuredHeight();

		//base原点中央
		t.textAlign="center";
		t.textBaseline="middle";
		if (shadow) {t.shadow=new createjs.Shadow(scolor,0,0,4);}//陰影

		//base表示
		if(!base) {t.visible=false;}

		//位置
		tpos_x +=w/2;//half
		contna.x=tpos_x;
		contna.y=tpos_y;//0

		//fill画像
		var canvas=document.createElement("canvas");
		canvas.width=CanvasW;
		canvas.height=CanvasH;
		var ctx=canvas.getContext("2d");

		//トリミング画像、X、Y、幅、高さ、
		var trimming_img=imageTrimmingCanvas(img,tpos_x,0,CanvasW,CanvasH,0,0,CanvasW,CanvasH);//X位置をずらした画像を得る
		var pattern=ctx.createPattern(trimming_img,"repeat");
		ctx.fillStyle=pattern;
		ctx.font=fontdata;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		ctx.globalAlpha=imgalpha;

		if (imgshadow) {set_shadow (ctx,scolor);}//陰影
		//fill
		ctx.lineWidth=outline_w;
		ctx.fillText(text,CanvasW/2,CanvasH/2);
		var img_txt=new createjs.Bitmap(canvas);
		img_txt.name="image";
		//原点中央
		img_txt.regX=CanvasW/2;
		img_txt.regY=CanvasH/2;

		//line
		var canvas=document.createElement("canvas");
		canvas.width=CanvasW;
		canvas.height=CanvasH;
		var ctx=canvas.getContext("2d");
		ctx.strokeStyle=lcolor;
		ctx.font=fontdata;
		ctx.textAlign="center";
		ctx.textBaseline="middle";
		ctx.lineJoin="miter";
		ctx.miterLimit=outline_w/2;

		if (shadow) {set_shadow (ctx,scolor);}//陰影
		//stroke
		ctx.lineWidth=outline_w;
		ctx.strokeText(text,CanvasW/2,CanvasH/2);
		var line_txt=new createjs.Bitmap(canvas);
		line_txt.name="line";
		//原点中央
		line_txt.regX=CanvasW/2;
		line_txt.regY=CanvasH/2;
		//base表示
		if(!line) {line_txt.visible=false;}

		//位置加算
		tpos_x +=(w/2+space);//half+space

		contna.width=w;
		contna.height=h;
		//contna.addChild(base_txt,img_txt,line_txt);
		contna.addChild(t,img_txt,line_txt);

		//コンテナ
		chip[i]=contna;
	}
	//戻り配列
	return chip;
}

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

//tickステージ
function tick() {
	stage.update();
}
//VIEWTEXT
function set_text(t) {
	viewtext.text=t;
}

//rainbow-Color
var rainbowColor=function(v,cv,saturation,lightness) {
	var no=v/cv*360;
	var color=createjs.Graphics.getHSL(no,saturation,lightness);
	return color;
}

//Textに陰影/RGB変換しない/Blur4
function set_shadow (ctx,color) {
	ctx.shadowColor=color;
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=4;//3-5
}

//トリミング画像、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;
}

//幅、高さ、画像
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;
}

//canvg専用
function canvgCanvas(w,h,svg) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//svg描画
	ctx.drawSvg(svg,0,0,w,h);

	return canvas;//element
}

//canvg-shadow専用
function canvgCanvasShadow(w,h,svg,shadow,scolor) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	if(shadow){set_shadow(ctx,scolor)};//陰影
	//svg描画
	ctx.drawSvg(svg,0,0,w,h);

	return canvas;//element
}
//--------------------------------------------------------------------------------------
//START
onload=init;

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


CSS

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


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

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


 

簡単な説明


[説明図]

 

canvgで画像化されたSVGを、CreateJS Bitmapクラスで表示します。テスト結果を以下に記述します。


1. デモではInkscapeで作ったSVGをローダーで読み込みます。
(Inkscapeで陰影処理したSVGは使用しないでください、エラーで処理が停止します)
2. canvgを使用して一旦SVGをラスター画像に変換したエレメントをBitmapクラスで表示します。
3. 実態は画像と同じですので、フエードなどの処理を画像同様に行えます。
4. Bitmapに陰影処理しているがChromeで陰影が付かない。(面倒だが付ける方法はあります)
5. デモでは 640x300サイズ のSVGを使用しています。


陰影をつける場合、SVG個別に処理する方が綺麗になるため複数に分解しています。


canvgのダウンロードなど

canvgは下記よりダウンロード出来ます。code.google.comから直接利用も可能です。
詳細はcanvgサイトを参照ください。

【canvg】code.google.com: Canvg


● CreateJS BitmapクラスでSVGを表示する
読み込めばBitmapクラスで表示するが、表示以外に色々な処理など行う場合は「読み込み完全終了」後行う。この点画像読み込みと同じである。

但し、平行するその他の処理で負荷が大きい時は「読み込み表示」が安定しないようです。特にIE系は不安定なので、ローダーを介して「読み込み完全終了」後に表示した方が良いと思われる。


canvgでSVGをラスター画像に変換


1. canvgの処理はCanvasに対して行われますので、処理用のCanvasでSVGを取り込み、
2. そのエレメントをBitmapクラスに取り込み表示する順序です。




BitmapクラスはCanvasエレメントを表示できる

インスタンス=new createjs.Bitmap(Canvasエレメント);

canvgのラスター処理 (画像化)

canvgのラスター処理には、canvg()、drawSvg()、の2つの方法があります。


1. CanvasエレメントにSVGを取り込む方法

一般的な、Html5 Canvasに表示する方法です。
ファイルから読み込む場合、ソースとなるSVGと対象のcanvasを指定するだけです。

CreateJSでは、使い難いので最終下段で少しだけ説明します。「 canvg()処理 」を参照ください。




canvg('対象canvas','ソースSVG.svg');

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

直接読み込む場合

canvg('対象canvas','<svg>SVGの描画内容</svg>');

使い難いので説明は後回しになります。


2. Canvasエレメントのコンテキスト(2d)にSVGを取り込む方法

こちらはコンテキスト(2d)での処理ですので、CreateJSでの利用を考慮すれば、上記方法より便利です。
(コンテキストの拡張処理になっている)




var canvas = document.getElementById("対象ID");
var ctx=canvas.getContext("2d");
ctx.drawSvg("ソースSVG.svg",X位置,Y位置,幅,高さ);

こちらを使用して処理しますので、説明は先になります。


drawSvg()処理

どちらの方法でも、Html5 Canvasに対する処理ですから、CreateJS Bitmapクラスで利用するために、一旦Canvasエレメントに描画してから、Bitmapクラスに取り込み表示します。この時点で画像同様のものとなります。
必要があれば、コンテキストに図形、テキストなど描画できますので利用価値があります。


● 1つのSVG処理

この処理を基本に工夫すれば色々と複雑な処理をも行えます。基本的には陰影は、親であるBitmapに処理しますがChromeで陰影が付かない不具合があります。(Chromeの事情でしょう)

Chromeで陰影を付ける場合は、下段の「 Chrome陰影処理 」を参照ください。




インスタンス=new createjs.Bitmap(canvgCanvas(幅,高さ,読み込んだSVG));
ステージまたはコンテナ.addChild(インスタンス);

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

//canvg専用
function canvgCanvas(w,h,svg) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//svg描画
	ctx.drawSvg(svg,0,0,w,h);

	return canvas;//element
}

drawSvg(svg,0,0,w,h)、としているのは、デモでは下図の様にSVGを同じ大きさで作っているためです。


 

● 複数のSVGを処理 1

但し、この関数では同じ大きさのSVGである事、コンテナにBitmap収容形式なためこれはコンテナで扱います。
個別にBitmap()収容していますので、陰影など違和感が無い。




コンテナインスタンス=new createjs.Bitmap(createVsgBox(幅,高さ,[読込SVG1,読込SVG2,読込SVG3,......]));
ステージまたはコンテナ.addChild(コンテナインスタンス);

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

//canvg専用複数
//分離しているから個別処理し易い
function createVsgBox(w,h,svgs) {
	var c=new createjs.Container();
	var canvas=[];
	//複数svg描画
	for (var i=0; i < svgs.length; i++) {
		canvas[i]=document.createElement("canvas");
		var ctx=canvas[i].getContext("2d");
		//指定の大きさになる
		canvas[i].width=w;
		canvas[i].height=h;
		//canvg描画
		ctx.drawSvg(svgs[i],0,0,w,h);
		//Bitmap化
		var bmp=new createjs.Bitmap(canvas[i]);
		bmp.shadow=shadow;//陰影処理
		bmp.id=i;
		c.addChild(bmp);
	}
	return c;//コンテナ

}

● 複数のSVGを処理 2

但し、この関数では同じ大きさのSVGである事。処理を簡略化しました。

陰影処理した場合、陰影など違和感があります。




インスタンス=new createjs.Bitmap(canvgMultiCanvas(幅,高さ,[読込SVG1,読込SVG2,読込SVG3,......]));
ステージまたはコンテナ.addChild(インスタンス);

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

//canvg専用複数
function canvgMultiCanvas(w,h,svgs) {
	var canvas=document.createElement("canvas");
	//svg描画
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	for (var i=0; i < svgs.length; i++) {
		//canvg
		ctx.drawSvg(svgs[i],0,0,w,h);
	}

	return canvas;//element
}

複数のSVGを処理 2b 書き方違うが上と同じ。

陰影処理した場合、陰影など違和感があります。




var インスタンス=screateVsgBitmap(幅,高さ,[読込SVG1,読込SVG2,読込SVG3,......]);
ステージまたはコンテナ.addChild(インスタンス);

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

//vsgBitmap/Bitmap()収容/drawSvg
function createVsgBitmap(w,h,svgs) {
	
	var canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//複数svg描画
	for (var i=0; i < svgs.length; i++) {
		//canvg描画
		ctx.drawSvg(svgs[i],0,0,w,h);
	}
	var bmp=new createjs.Bitmap(canvas);

	return bmp;//Bitmap

}

通常のコンテキスト描画との混在

必要があれば、コンテキストに図形、テキストなどの混在させて描画できますので利用価値があります。当然、「重なり順」は表記順に成ります。




//canvg専用
function canvgCanvasXXX(w,h,svg) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//通常描画
	ctx.fillStyle="#FF0000";
	ctx.fillRect(0,0,w,h);
	//svg描画
	ctx.drawSvg(svg,0,0,w,h);

	return canvas;//element
}

トリミング処理

画像に変換しているので、トリミングが出来ます。其の範囲などは自由に決められます。
デモではステージの大きさと同じ640x300でSVGを作っていますので、次の様に処理しました。数値は大体の値です。


1. SVGをcanvgで画像化します。
2. 画像ならdrawImage()でトリミングが出来ますので、文字表示部位をトリミングします。
3. 自動では成りませんので、トリミング位置などは使用者が決定します。


例は、470x86 の大きさでトリミング、同じ位置に配置する場合です。1ピクセル位のズレはあるでしょう。




var svgImage;
コンテナsvgcontainerがステージに有り、ステージきさはcanvasWidth,canvasHeight、
読み込みSVGはsvgfiles[0]とする

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

//画像化
var elm=canvgCanvas(canvasWidth,canvasHeight,svgfiles[0]);//canvg
//トリミング
elm=imageTrimmingCanvas(elm,86,76,470,86,0,0,470,86);
svgImage=new createjs.Bitmap(elm);
svgImage.regX=470/2;
svgImage.regY=86/2;
svgImage.shadow=shadow;
//表示
svgcontainer.addChild(svgImage);
svgcontainer.x=canvasWidth/2;
svgcontainer.y=76+86/2;

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

//トリミング画像、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;
}


陰影処理

Inkscapeでも陰影処理できますが、VSGをcanvgで画像化処理した時「エラー」になりますので、原則、CreateJSのShadowクラスで陰影を付けています。
VSG描画も1つにまとめることが出来ますが、陰影を個別につけたほうが綺麗になるため3つに分離しています。


Chrome陰影処理

Canvasエレメントでの「Canvasドロップシャドウ」処理をすれば、Chromeでも陰影を付けることが出来ます。

こちらの陰影処理の場合は、親であるBitmapなどでの陰影は不要です。色は16進カラーで指定しています。
陰影処理は必ず、下の例のように「svg描画」の直前に行ってください。追加の図形テキストなど挿入した場合、意図しなく陰影が付く場合があります。




//Canvas-Shadowの処理
//幅、高さ、SVG、陰影、陰影色(16進カラー指定)
svgImage=new createjs.Bitmap(canvgCanvasShadow(canvasWidth,canvasHeight,svgfiles[0],true,"#000000"));

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

//canvg-shadow専用
function canvgCanvasShadow(w,h,svg,shadow,scolor) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	if(shadow) {set_shadow(ctx,scolor)};//陰影
	//svg描画
	ctx.drawSvg(svg,0,0,w,h);

	return canvas;//element
}

-------------------------------------------------------------
下の関数が必要です、変更可

//Textに陰影Blur4/RGB変換しない
function set_shadow (ctx,color) {
	ctx.shadowColor=color;
	ctx.shadowOffsetX=0;
	ctx.shadowOffsetY=0;
	ctx.shadowBlur=4;//3-5
}

● 陰影をクリアする
コンテキストctxは1つですから、陰影処理指定した所から上に意図シナクトモ陰影処理されます。もし陰影を付けたくなければ、途中で「透明の色」を指定すればそれ以降陰影は付きません。


ctx.shadowColor='rgba(0,0,0,0)';

Canvas shadowColor はRGB変換しなくとも設定できるようなので、簡略化(ゴマカス)しました。2014/09/02より変更
shadowColor、はCSSで指定できる色形式だそうだ。例、"#000000"、"black"、"rgb(0,0,0)"、...


加工処理

前ページの処理では画像で無いためフエードなど出来ない処理がありました。
canvgで表示するため、SVGは画像化されます。よってフエード、画像分割、トリミングなども従来通り可能です。
画像化されたことにより拡大した場合は当然粗くなります。

 


 

canvg()処理

こちらの処理でも表示は出来ますが、使い勝手が良く有りませんので注意ください。参考まで記載しておきます。
Canvasエレメントのコンテキストに描画していないので、汎用性が無いのが欠点のようです。


但し、canvg()には第3引数のオプション設定が可能ですので場合によっては、こちらの処理が必要になる場合もあるかも知れません。

オプション設定詳細は、canvgサイトにて確認ください。




インスタンス=new createjs.Bitmap(canvgCanvas2(幅,高さ,読み込んだSVG));
ステージまたはコンテナ.addChild(インスタンス);

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

//canvg専用、canvg取り込み画像化処理
function canvgCanvas2(w,h,svg) {
	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	//canvg/svg描画
	canvg(canvas,svg);

	return canvas;//element
}

● 複数の場合

複数の場合は重ねるが、前の画像に「重ね描き」されるので、オプション設定をします。
ただ重ねていますので、この場合陰影に少し違和感がでます。
コンテナ収容で返していますが、個別にBitmap化してaddChildすれば陰影は正常にはなるでしょう。




コンテナインスタンス=createVsgBox2(幅,高さ,[読込SVG1,読込SVG2,読込SVG3,......]);
ステージまたはコンテナ.addChild(コンテナインスタンス);

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

//vsgBox/canvg、コンテナBitmap()収容、特殊なかさね
function createVsgBox2(w,h,svgs) {
	var c=new createjs.Container();
	//複数svg描画
	canvas=document.createElement("canvas");
	//指定の大きさになる
	canvas.width=w;
	canvas.height=h;
	for (var i=0; i < svgs.length; i++) {
		//canvg/消去せずかさねる/無闇にtrueを返す関数を渡すとシステムに無用な負荷がかかる
		canvg(canvas,svgs[i],{ignoreDimensions:true,ignoreClear:true});
	}
	//一括Bitmap化
	var bmp=new createjs.Bitmap(canvas);
	bmp.shadow=shadow;
	c.addChild(bmp);
	return c;//コンテナ

}

コンテキストで他の図形などをも追加描画できる情報がありましたが、canvg()処理の場合CreateJSでは出来ないようです。(方法が悪いのかもしれませんが?、この点現在不明です)


画像

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


canvgについては、は以下の記事を参考にしました。

【参考】www.h2.dion.ne.jp記事: svg要素の基本的な使い方まとめ

【参考】curtaincall.weblike.jp記事: JAVASCRIPTでSVGをラスター画像に変換



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

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


 

ゴマカシながらで、江戸の町もこれで一件落着、以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]