POPSブログ

CreateJS Round PolyStar 角丸多角形の描画

290

  Category:  javascript2014/04/12 pops 

一般的な多角形の描画はCreateJS Graphicsクラスにありますが、角丸多角形は新たに作らねばなりません。GraphicsクラスとCanvasエレメントをBitmap()で表示する、2つの方法で描画してみます。それぞれ quadraticCurveTo()、arcTo()、の2つの形式で描画しますので表現が多彩です。
easeljs-0.7.1 でのテストです。

 

CreateJS Round PolyStar 角丸多角形の描画テスト


Canvasエレメントに描画する順序をGraphicsクラスに振り返ればよいのですが、結構思うように描けないのが現実です。beginPath()、moveTo()、の使い方次第で大きく変わりますのでこの辺が「ミソ」のようです。
easeljs-0.7.1 を使用します。(easeljs-0.7.0でも問題はありません)


 

DEMO


CreateJS Round PolyStar 角丸多角形の描画デモ、(createJS074.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="800" height="400"></canvas>
	</div>
</div>

JS

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


//日本語
//createJS074.js
//RoundPolyStar
//easeljs-0.7.1デモ用

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

//説明TEXT
var textUse=true;

//画像リスト
var manifest=[
{src:"/main/images/sp_back_640.jpg",id:"back"},
{src:"/main/images/sp_back2_640.jpg",id:"back"},
{src:"/main/images/sp_back3_640.jpg",id:"back"},
{src:"/main/images/hf015.gif",id:"back"},
];

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

//ステージ
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/最下位色背景層、無くとも良い"#B0C4DE"
	backrect=new createjs.Shape();
	backrect.graphics.beginFill("#FFFFFF").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() {

	//--------------Canvas Bitmap収容表示--------------------

	//---------1----------
	set_memo(40,15,"1 Canvas quadraticCurveTo");
	//トリミング画像
	var img=imageTrimmingCanvas(assets[0],120,100,200,200,0,0,200,200);
	var angle=0;//デグリー値
	//img=null;

	//createPolyStarCanvas
	//ベース幅、ベース高さ、ベース色、分割数、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
	//(bw,bh,bscolor,division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
	var star=createPolyStarCanvas(200,200,'rgba(0,0,0,0)',24,100,80,'#9400D3',img,'#FFFFFF',2,true,'#000000',true,angle);
	var starBox=new createjs.Bitmap(star);
	starBox.regX=100;
	starBox.regY=100;
	starBox.x=110;
	starBox.y=120;
	mainContainer.addChild(starBox);

	//---------2----------
	set_memo(230,15,"2 Canvas quadraticCurveTo");
	img=assets[1];
	angle=360/20;//デグリー値
	//img=null;

	//createPolyStarCanvas2
	//ベース幅、ベース高さ、ベース色、分割数、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
	var star=createPolyStarCanvas(200,200,'rgba(0,0,0,0)',5,120,60,'#9400D3',img,'#FFFFFF',2,true,'#000000',true,angle);
	var starBox2=new createjs.Bitmap(star);
	starBox2.regX=100;
	starBox2.regY=100;
	starBox2.x=300;
	starBox2.y=120;
	mainContainer.addChild(starBox2);

	//---------3----------
	set_memo(450,15,"3 Canvas arcTo");
	img=assets[2];
	angle=0;//デグリー値
	//img=null;

	//LinearGradientBox
	//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
	img=createLineGradBox (200,200,"#9400D3","#000000","#000000","y",2);

	//createPolyStarArcToCanvas
	//ベース幅、ベース高さ、ベース色、分割数、先端半径、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
	//(bw,bh,bscolor,division,radius,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
	var star=createPSCanvas(200,200,'rgba(0,0,0,0)',9,10,90,70,'#9400D3',img,'#FFFFFF',2,true,'#000000',true,angle);
	var starBox3=new createjs.Bitmap(star);
	starBox3.regX=100;
	starBox3.regY=100;
	starBox3.x=500;
	starBox3.y=120;
	mainContainer.addChild(starBox3);

	//---------4----------
	set_memo(640,15,"4 Canvas arcTo");
	img=assets[2];
	angle=0;//デグリー値
	//img=null;

	//createPolyStarArcToCanvas
	//ベース幅、ベース高さ、ベース色、分割数、先端半径、外半径、内半径、内部色、パタン画像、画像幅、画像高さ、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
	//(bw,bh,bscolor,division,radius,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
	var star=createPSCanvas(200,200,'rgba(0,0,0,0)',13,5,100,50,'#9400D3',img,'#FFFFFF',2,true,'#000000',true,angle);
	var starBox4=new createjs.Bitmap(star);
	starBox4.regX=100;
	starBox4.regY=100;
	starBox4.x=700;
	starBox4.y=120;
	mainContainer.addChild(starBox4);


	//--------------CreateJS Shapeコンテナ収容--------------------

	//---------5----------
	set_memo(40,250,"5 CreateJS quadraticCurveTo");
	img=assets[0];
	//img=null;

	//matrix補正用画像の大きさ
	var imgWidth=640;
	var imgHeight=400;

	angle=0;//デグリー値
	//分割数、外半径、内半径、内部色、パタン画像、画像幅、画像高さ、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
	//(division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
	var starBox5=createRoundStarGraphics(5,120,60,'#9400D3',img,imgWidth,imgHeight,'#FFFFFF',2,true,'#000000',true,angle);
	starBox5.x=300;
	starBox5.y=300;
	mainContainer.addChild(starBox5);

	//---------6----------
	set_memo(500,250,"6 CreateJS arcTo");
	img=assets[1];
	//img=null;

	//matrix補正用画像の大きさ
	var imgWidth=640;
	var imgHeight=400;

	angle=0;//デグリー値
	//分割数、先端半径、外半径、内半径、内部色、パタン画像、画像幅、画像高さ、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
	//(division,radius,innerR,outerR,pcolor,patternimg,imgwidth,imgheight,lcolor,linewidth,line,scolor,shadow,angle)
	var starBox6=createArcToStarGraphics(13,5,100,50,'#9400D3',img,imgWidth,imgHeight,'#FFFFFF',2,true,'#000000',true,angle);
	starBox6.x=700;
	starBox6.y=300;
	mainContainer.addChild(starBox6);

}

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

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

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

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

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

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

//RadialGradientBoxGradient
//幅、高さ、色1、色2、タイプ0-4
function createRadialGradBox (w,h,color1,color2,type) {

	var canvas=document.createElement("canvas");
	canvas.width=w;
	canvas.height=h;
	var ctx=canvas.getContext("2d");
	//タイプ修正
	if(!type){type=0;}
	if(type > 4){type=0;}

	//RadialGradient
	var px=[w/2,0,w,w,0];
	var py=[h/2,0,0,h,h];
	var x=px[type];
	var y=py[type];
	var r=w*0.5;
	if(type > 0) {r=w;}
	var gradient;
	gradient=ctx.createRadialGradient(x,y,20,x,y,r);

    	gradient.addColorStop(0,color1);
	gradient.addColorStop(1,color2);

	ctx.fillStyle=gradient;
	//FILL
	ctx.fillRect(0,0,w,h);

	return canvas;
}

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

//createPolyStarCanvas
//ベース幅、ベース高さ、分割数、ベース色、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(bw,bh,bscolor,division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
function createPolyStarCanvas (bw,bh,bscolor,division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle) {

	if(!angle) {angle=0;}

	//Box
	var canvas=document.createElement("canvas");
	canvas.width=bw;
	canvas.height=bh;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=bscolor;
	ctx.fillRect(0,0,bw,bh);

	ctx.lineCap="butt";
	ctx.lineWidth=linewidth;
	ctx.strokeStyle=lcolor;
	ctx.fillStyle=pcolor;

	//flicker揺らぎ/0.1-0.2
	var flicker=0;

	//中心補正
	var base_x=bw/2;
	var base_y=bh/2;

	//1 FILL
	//パタン画像
	if(patternimg){
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.fillStyle=pattern;
	} else{
		ctx.fillStyle=pcolor;
	}
	//描画データ
	var cx,cy,cx2,cy2,cx3,cy3;
	var cAngle=angle*createjs.Matrix2D.DEG_TO_RAD;
	var nAngle;

	//ライン描画
	nAngle=Math.PI*2/division;
	hfAngle=nAngle/2;

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

		//回転補正
		cAngle +=nAngle;

		//#CCCCCC
		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		cx2=Math.cos(cAngle+hfAngle+flicker)*innerR;
		cy2=Math.sin(cAngle+hfAngle+flicker)*innerR;
		cx3=Math.cos(cAngle+hfAngle*2)*outerR;
		cy3=Math.sin(cAngle+hfAngle*2)*outerR;

		//中も描く、凹凸OK
		if(i == 0) {ctx.moveTo(base_x,base_y);}
		ctx.lineTo(cx+base_x,cy+base_y);
    		ctx.quadraticCurveTo(cx2+base_x,cy2+base_y,cx3+base_x,cy3+base_y);
		ctx.lineTo(base_x,base_y);
/*
		//こちらもOKだが凹の場合乱れる
		if(i == 0) {ctx.moveTo(cx+base_x,cy+base_y);}
		ctx.quadraticCurveTo(cx2+base_x,cy2+base_y,cx3+base_x,cy3+base_y);
*/
		if(shadow && i == division-1) {set_shadow (ctx,scolor);}//Safari OK
		ctx.fill();
		//ctx.stroke();

	}

	//2 LINE
	if(line) {
		//描画データ
		cAngle=angle*createjs.Matrix2D.DEG_TO_RAD;
		nAngle=0;

		nAngle=Math.PI*2/division;
		hfAngle=nAngle/2;

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

			//回転補正
			cAngle +=nAngle;

			//位置計算
			cx=Math.cos(cAngle)*outerR;
			cy=Math.sin(cAngle)*outerR;
			cx2=Math.cos(cAngle+hfAngle+flicker)*innerR;
			cy2=Math.sin(cAngle+hfAngle+flicker)*innerR;
			cx3=Math.cos(cAngle+hfAngle*2)*outerR;
			cy3=Math.sin(cAngle+hfAngle*2)*outerR;
			//ライン描画
			ctx.strokeStyle=lcolor;
			ctx.beginPath();
			ctx.moveTo(cx+base_x,cy+base_y);
    			ctx.quadraticCurveTo(cx2+base_x,cy2+base_y,cx3+base_x,cy3+base_y);
			//陰影a=0で消す
			if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
			ctx.stroke();

		}
	}

	return canvas;
}

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

//createPolyStarArcToCanvas
//ベース幅、ベース高さ、ベース色、分割数、先端半径、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(bw,bh,bscolor,division,radius,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
function createPSCanvas (bw,bh,bscolor,division,radius,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle) {

	if(!angle) {angle=0;}

	//Box
	var canvas=document.createElement("canvas");
	canvas.width=bw;
	canvas.height=bh;
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=bscolor;
	ctx.fillRect(0,0,bw,bh);

	ctx.lineCap="butt";
	ctx.lineWidth=linewidth;
	ctx.strokeStyle=lcolor;
	ctx.fillStyle=pcolor;

	//中心補正
	var base_x=bw/2;
	var base_y=bh/2;

	//flicker揺らぎ/0.1-0.2
	var flicker=0;

	//1 FILL
	//パタン画像
	if(patternimg){
		var pattern=ctx.createPattern(patternimg,"repeat");
		ctx.fillStyle=pattern;
	} else{
		ctx.fillStyle=pcolor;
	}
	//描画データ
	var cx,cy,cx2,cy2,cx3,cy3;
	var cAngle=angle*createjs.Matrix2D.DEG_TO_RAD;
	var nAngle;

	nAngle=Math.PI*2/division;
	hfAngle=nAngle/2;

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

		//回転補正
		cAngle +=nAngle;

		//#CCCCCC
		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		cx2=Math.cos(cAngle+hfAngle+flicker)*innerR;
		cy2=Math.sin(cAngle+hfAngle+flicker)*innerR;
		cx3=Math.cos(cAngle+hfAngle*2)*outerR;
		cy3=Math.sin(cAngle+hfAngle*2)*outerR;
		//中も描く
		if(i == 0) {ctx.moveTo(base_x,base_y);}

		//Fill、凹凸OK
		ctx.lineTo(cx+base_x,cy+base_y);
		ctx.arcTo(cx2+base_x,cy2+base_y,cx3+base_x,cy3+base_y,radius);
		ctx.lineTo(cx3+base_x,cy3+base_y);
		ctx.lineTo(base_x,base_y);

		if(shadow && i == division-1) {set_shadow (ctx,scolor);}
		ctx.fill();

	}

	//2 LINE
	if(line) {
		//描画データ
		cAngle=angle*createjs.Matrix2D.DEG_TO_RAD;
		nAngle=0;

		//ライン描画
		nAngle=Math.PI*2/division;
		hfAngle=nAngle/2;

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

			//回転補正
			cAngle +=nAngle;

			//位置計算
			cx=Math.cos(cAngle)*outerR;
			cy=Math.sin(cAngle)*outerR;
			cx2=Math.cos(cAngle+hfAngle+flicker)*innerR;
			cy2=Math.sin(cAngle+hfAngle+flicker)*innerR;
			cx3=Math.cos(cAngle+hfAngle*2)*outerR;
			cy3=Math.sin(cAngle+hfAngle*2)*outerR;

			//Line描画
			ctx.strokeStyle=lcolor;
			ctx.beginPath();
			ctx.moveTo(cx+base_x,cy+base_y);
			ctx.arcTo(cx2+base_x,cy2+base_y,cx3+base_x,cy3+base_y,radius);
			ctx.lineTo(cx3+base_x,cy3+base_y);

			//陰影a=0で消す
			if(shadow) {ctx.shadowColor="rgba(0,0,0,0)";}
			ctx.stroke();

		}
	}

	return canvas;
}

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

//CreateJS Shapeコンテナ収容
//分割数、外半径、内半径、内部色、パタン画像、画像幅、画像高さ、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
function createRoundStarGraphics (division,innerR,outerR,pcolor,patternimg,imgwidth,imgheight,lcolor,linewidth,line,scolor,shadow,angle) {

	if(!angle) {angle=0;}
	//コンテナ
	var wrap=new createjs.Container();
	//graphicのスタイル
	var graphics=new createjs.Graphics();
	var graphics2=new createjs.Graphics();
	graphics2.ss(linewidth,"butt");

	//画像塗りこみ位置補正
	if(patternimg) {
		var matrix=new createjs.Matrix2D;
		matrix.translate(imgwidth/2,imgheight/2);
	}

	//flicker揺らぎ/0.1-0.2
	var flicker=0;

	//描画データ
	var cx,cy,cx2,cy2,cx3,cy3;
	var cAngle=angle*createjs.Matrix2D.DEG_TO_RAD;
	var nAngle;

	//ライン描画
	nAngle=Math.PI*2/division;
	hfAngle=nAngle/2;

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

		//回転補正
		cAngle +=nAngle;

		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		cx2=Math.cos(cAngle+hfAngle+flicker)*innerR;
		cy2=Math.sin(cAngle+hfAngle+flicker)*innerR;
		cx3=Math.cos(cAngle+hfAngle*2)*outerR;
		cy3=Math.sin(cAngle+hfAngle*2)*outerR;

		//Fill、凹凸OK
		if(i == 0) {//重要
			//内部塗り
			if(!patternimg){graphics.beginFill(pcolor);}
			if(patternimg){graphics.beginBitmapFill(patternimg,"repeat",matrix);}//Matrix
		}

		//
		if(i == 0) {graphics.moveTo(cx,cy);}
		graphics.quadraticCurveTo(cx2,cy2,cx3,cy3);
		

		//Line
		if(line){

			//ライン描画
			graphics2.beginStroke(lcolor);
			graphics2.moveTo(cx,cy).quadraticCurveTo(cx2,cy2,cx3,cy3);

		}

	}

	//Shapeに格納
	var shape=new createjs.Shape(graphics);
	if(shadow){shape.shadow=new createjs.Shadow(scolor,0,0,5);}//陰影
	var shape2=new createjs.Shape(graphics2);
	wrap.addChild(shape,shape2);

	return wrap;
}


//CreateJS Shapeコンテナ収容
//分割数、先端半径、外半径、内半径、内部色、パタン画像、画像幅、画像高さ、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(division,radius,innerR,outerR,pcolor,patternimg,imgwidth,imgheight,lcolor,linewidth,line,scolor,shadow,angle)
function createArcToStarGraphics (division,radius,innerR,outerR,pcolor,patternimg,imgwidth,imgheight,lcolor,linewidth,line,scolor,shadow,angle) {

	if(!angle) {angle=0;}
	//コンテナ
	var wrap=new createjs.Container();
	//graphicのスタイル
	var graphics=new createjs.Graphics();
	var graphics2=new createjs.Graphics();
	graphics2.ss(linewidth,"butt");

	//flicker揺らぎ/0.1-0.2
	var flicker=0;

	//画像塗りこみ位置補正
	if(patternimg) {
		var matrix=new createjs.Matrix2D;
		matrix.translate(imgwidth/2,imgheight/2);
	}

	//描画データ
	var cx,cy,cx2,cy2,cx3,cy3;
	var cAngle=angle*createjs.Matrix2D.DEG_TO_RAD;
	var nAngle;

	//ライン描画
	nAngle=Math.PI*2/division;
	hfAngle=nAngle/2;

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

		//回転補正
		cAngle +=nAngle;

		cx=Math.cos(cAngle)*outerR;
		cy=Math.sin(cAngle)*outerR;
		cx2=Math.cos(cAngle+hfAngle+flicker)*innerR;
		cy2=Math.sin(cAngle+hfAngle+flicker)*innerR;
		cx3=Math.cos(cAngle+hfAngle*2)*outerR;
		cy3=Math.sin(cAngle+hfAngle*2)*outerR;

		//Fill、凹凸OK
		if(i == 0) {//重要
			//内部塗り
			if(!patternimg){graphics.beginFill(pcolor);}
			if(patternimg){graphics.beginBitmapFill(patternimg,"repeat",matrix);}//Matrix
		}

		graphics.lineTo(cx,cy)
		.arcTo(cx2,cy2,cx3,cy3,radius)
		.lineTo(cx3,cy3).lineTo(0,0);

		//Line
		if(line){
			graphics2.beginStroke(lcolor).moveTo(cx,cy);
			graphics2.arcTo(cx2,cy2,cx3,cy3,radius);
			graphics2.lineTo(cx3,cy3);
		}

	}

	//Shapeに格納
	var shape=new createjs.Shape(graphics);
	if(shadow){shape.shadow=new createjs.Shadow(scolor,0,0,5);}//陰影
	var shape2=new createjs.Shape(graphics2);
	wrap.addChild(shape,shape2);

	return wrap;
}

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

//START
init();

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


CSS

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


/*日本語 createJS074.css*/

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

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

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


簡単な説明


Round PolyStar 角丸多角形の描画


CreateJS GraphicsクラスとCanvasエレメントをBitmap()で表示する、2つの方法で描画してみます。
Canvasエレメントで描画する場合は少々面倒ですが細やかな処理が可能と思います。

図形を角丸にすることにより、表現が違い、設定如何では面白い図形の表現も可能ですので結構使い道があるように思います。


[説明図]

 

1. 半径の設定次第で逆向きに出来ます。(半径の値で表示状況を見ながら調整)
2. 画像の埋め込みが可能です。グラデーションも可能。
(画像利用の場合は完全に読み込み完了の画像を使用ください)
3. ラインと分離しています、陰影は下のFill部分に処理しています。
(それぞれ表示、非表示の切り替えが可能です)
4. 少々の揺らぎを与えて、変形も可能です。(引数では対処していない)
5. quadraticCurveTo()、arcTo()、の2つの形式で描画します。
6. バージョン 0.7.0 でも一応動作可能です。


Operaでの arcTo() の不具合がありましたが、Chromeの描画エンジンに移行していますので、今後は arcTo() は補正せずにそのまま使用します。(Operaのシェアは非常に小さい)


 

CanvasエレメントをBitmap()で表示する方法

CreateJS Graphicsクラスを利用せず、Html5 Canvasの描画規則に従い描画作業を行うものです。多少細やかな処理ができ、表示の際にのみBitmap()を利用します。


1. Canvasエレメントの大きさの範囲内に描画されます。範囲外の描画は表示されません。
(Canvasエレメントの透明度を一時的に変えると配置状況がわかる)
2. 出来上がったものは画像同然のものですからBitmap()で表示します。
3. 画像を合わせ易いのが特徴です。
4. 1枚の画像と同じですから、中に描いた要素を直接CreateJSで制御は出来ません。
(但し、親になる、Bitmap()はCreateJSで制御できます)


設定

サンプル[1]では以下のようになります。他も同様です。


//createPolyStarCanvas
//ベース幅、ベース高さ、ベース色、分割数、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(bw,bh,bscolor,division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
var star=createPolyStarCanvas(200,200,'rgba(0,0,0,0)',24,100,80,'#9400D3',img,'#FFFFFF',2,true,'#000000',true,angle);

● ベースの大きさを明示して、中の部材を配置する。
一旦、透明度を変えるとベースの大きさがわかります。最後に元の透明度に戻します。


var star=createPolyStarCanvas(200,200,'rgba(0,0,0,0.5)',.....)

本来必要ではないが、確認用に設定しています。


● 分割数
分割(division)は自由ですが、原則 3分割 以上になります(2分割も可能)。(出来上がりは上図参照)

quadraticCurveTo処理タイプは、「内半径の位置」を「始点、終点」とし「外半径の位置」を「制御点」として曲線がえがかれます。半径の差分が形を決めるポイントです。
arcTo処理タイプは、「先端半径」の満たす「線分上」で角丸処理されます。「先端半径」の大きさが形を決めるポイントです。「先端半径」が小さいと「とがり」、大き過ぎると別形状になる。
ともに、描画状況を見ながら調整します。


● arcToでの「先端半径」
始めは「半径」を小さくして状況を確認してから、好みの「半径」にします。大きな半径を設定すると意図しない描画になりやすいので注意ください。(下図参照)


● arcToでの描画

arcToでの描画は理解しにくい。角丸を描くために、2つのラインに接する「弧」を描いているのでラインの「終点」位置を明確にしないと「弧」の「終点」を計算できないのでそのために設定させられるのである。
(arcTo()で図のように赤い部分が描画される、黄色のラインは描画されない)
この位置は内部的に保存されているので、「弧」の「終点」からラインを引くならば、arcTo()の後に、ラインの「終点」位置に向かって .lineTo() を実行すれば良い。



ctx.moveTo(始点X,始点Y);//描画始点に移動
ctx.arcTo(交差点X,交差点Y,終点X,終点Y,角丸半径);//角丸の終点まで描画
ctx.lineTo(終点X,終点Y);//終点までラインを描画

Fillの場合は、時として図形の中心からラインを引かねばならない事もある。moveTo()、beginPath()、によっても変わるし、実際描いてみないとわからない部分も多い。
ラインが交差すると塗りも変わるので、交差しないようにポイントを設定しなければならない。結構面倒である。


CreateJS Graphicsクラスにするには、上記の方法を、Graphicsクラスの書式に振り替えると概ね旨く描画できる。


● 陰影とライン
陰影とラインはともに true で設定します。false で設定の解除になります。
注意、ラインに陰影はつきません。ライン幅が大きいと陰影が見えない場合があります。


● 中の図形の回転角度を変える
角度を変えるには angle で調整します。値はデグリー値で与えますが、ラジアンに変換しています。
図のように頂点の角度(位置)が異なりますので修正する場合は、旨く合わせてください。

サンプル[2] では5角形の頂点が上になるように、下記のように修正している。


angle=360/20;//デグリー値

● グラデーション塗りにしたい場合 (LinearGradient)


グラデーション塗りの「Canvasエレメント」を画像の代わりに挿入します。サンプル[3] では以下のようにしています。


//LinearGradientBox
//幅、高さ、色1、色2、色3、方向(x.y)、タイプ(2.3)
img=createLineGradBox (200,200,"#9400D3","#000000","#000000","y",2);

● グラデーション塗りにしたい場合2 (RadialGradient)
グラデーション塗りの「Canvasエレメント」を画像の代わりに挿入します。サンプルはありません。


//LinearGradientBox
//幅、高さ、色1、色2、タイプ(0-4)
img=createRadialGradBox (w,h,color1,color2,type);

一応、9種のパターンで、色指定もできますので通常はこれで十分と思います。


● 画像を使用しない
画像を使用しない場合は、画像を null にしますと、その時設定の「背景色」(内部色)で染められます。
rgba(0,0,0,0)のような、RGBA指定も可能ですが、アルファ値 0 では陰影はつきません。


img=null;

塗りこむ画像をトリミングして合わせる

 

通常、画像はCanvasエレメントの原点00、左上に合わせられますので、画像の状況では旨く合わない時もあります。
画像は、Canvasエレメントの大きさに合わせたほうがよい。トリミングは サンプル[1] のようにすれば良い。

drawImage()で指定位置をトリミングしているだけ。(画像範囲外を指定するとブラウザによりエラーになることがある)


//トリミング画像
//(画像result値,元画像X,元画像Y,元画像幅,元画像高さ,0,0,画像幅,画像高さ)
var img=imageTrimmingCanvas(assets[0],120,100,200,200,0,0,200,200);

トリミングしないならば、Canvasエレメントの大きさの画像を用意すれば良い。


透過画像を塗りこんだ場合の陰影

透過画像を塗りこんだ場合の陰影のつき方はバラバラです。画像のある部分に陰影がつきます。
Chrome以外の場合は中の画像にも陰影がつきます。修正するには、新たに最下位層を作りそこに陰影をかけるように構造の作り変えが必要ですから対処しません。(下図参照)


角丸正多角形の描画

上記の「arcToでの描画」は全て「星形」になりますが、2つの半径を旨くあわせれば「正多角形」にもなります。この条項は、2014/04/14 追記します。

角度とそれぞれの半径の関係は、図のようになりますので、計算式で正確な半径を求めることができます。



var division=5;
var innerR=90;
//outerRを中間に強制変更
var outerR=Math.cos(Math.PI/division)*innerR;

//createPolyStarArcToCanvas
//ベース幅、ベース高さ、ベース色、分割数、先端半径、外半径、内半径、内部色、パタン画像、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(bw,bh,bscolor,division,radius,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
var star=createPSCanvas (200,200,'rgba(0,0,0,0)',division,10,innerR,outerR,'#9400D3',img,'#FFFFFF',2,true,'#000000',true,angle);

これで「arcTo」で「角丸正多角形」の描画ができます。ただし角丸の径が小さく見えますのでこの辺は修正します。


今までは、createXxxx (){.... }の形ですが、
CreateJSのGraphicsクラス、.drawPolyStar(.....) の形式で書けたら便利です。
Graphicsクラスにメソッドを追加して、連続でかけるようにテストしたら旨く描画するようなので、次回にまとめて見ます。


 

CreateJS Graphicsクラスで描画する方法


上記の処理を、Graphicsクラスの表記方法に置き換えただけですが、原点のつくりの違いで、図のように画像配置が違いますので、Matrix処理で画像位置を移動補正します。


1. 図形の中心に画像の中心が来るように、Matrix処理で画像位置を移動補正する。
2. Graphicsクラスで処理しますから、図形の大きさに制約はありません。
3. 「Canvasエレメント」と違って、中の要素にアクセスできる。
4. 画像の大きさを引数に加える違いがあるが、その他は同じです。
5.「Canvasエレメント描画」のものを、Graphicsクラスに修正しただけです。


複雑な場合は一旦、Canvasエレメントで描画して確認し、Graphicsクラスに置き換えするようにしないと思い通りの描画はできない。特に arcTo() は面倒です。


設定

サンプル[5]では以下のようになります。他も同様です。


//分割数、外半径、内半径、内部色、パタン画像、画像幅、画像高さ、ライン色、ライン幅、ライン、陰影色、陰影、角度補正
//(division,innerR,outerR,pcolor,patternimg,lcolor,linewidth,line,scolor,shadow,angle)
var starBox5=createRoundStarGraphics(5,120,60,'#9400D3',img,imgWidth,imgHeight,'#FFFFFF',2,true,'#000000',true,angle);

他の引数の設定などは同じです。個人的には前述の「Canvasエレメントで描画」を利用した方が細やかな処理ができると思いますが...、この辺は好みの問題です!


● 上記設定以外の説明は、前述の「Canvasエレメントで描画」と同じですので省略します。

● 画像処理では graphics.beginBitmapFill() を利用していますので「Canvasエレメント」の挿入も可能です。


以上のJSの改造は自由です。目的によっては改造しなければならない事もあるかと思います...
旨く改造できない時はうれしいことに「悩む」権利が与えられますから、骨折しない程度頭をひねってください。


使用画像

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


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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]