POPSブログ

CreateJS Graphicsクラスを拡張して 扇形、弧状図形描画

293

  Category:  javascript2014/04/29 pops 

Graphicsクラスを拡張してメソッドにする事により、通常のCreateJS Graphicsクラスの書式で記述できる。扇形、弧状図形を描画してみる。円グラフを描画するに便利かも知れない。
easeljs-0.7.1 でのテストです。

 

CreateJS Graphicsクラスを拡張して 扇形、弧状図形描画 テスト


Graphicsクラスを拡張の「元ネタ」は以前にも書いたが、下記記事である。


【参考】jsdo.itの記事: EaselJS 拡張 ~ 部分円の描画 ~


easeljs-0.7.1 を使用します。(easeljs-0.7.0でも問題はありません)


 

Graphicsクラスを拡張してメソッドにする事により以下の様な書き方が出来るのが便利です。



Graphicsクラスインスタンス.graphics.ss(1).s("#FFFFFF").beginFill("#FF0000").drawCircleEx(x,y,半径,開始角度,終了角度);

 

DEMO


CreateJS 扇形、弧状図形描画デモ、(createJS077.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>

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


HTML (HTML5)


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

JS

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


//日本語
//createJS077.js
//弧状図形
//easeljs-0.7.1デモ用

//------------------------------------------------------
//初期設定
//canvasの大きさ
var canvasWidth=900;
var canvasHeight=400;
//説明TEXT
var textUse=true;
//ステージ
var stage;
//コンテナ
var mainContainer;
//簡易TEXT
var viewtext;

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

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

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

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

	//バックRect/最下位色背景層、無くとも良い
	var 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);

	//表示に進む
	main();

}


//Main
function main() {

	//サンプル1-10コンテナ収容

	//---------1----------
	set_memo(10,15,"1 CreateJS drawCircleEx");

	var sides=24;//分割数
	var radius=80;
	var angle=0;//-Math.PI/2;//角度補正12時

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=Math.PI*2/sides;//角度
	for (var i=0; i<sides; i++) {

		var rainbowColor=createjs.Graphics.getHSL(i/sides*360,100,50);//直接
		//Fill/line
		box.graphics.ss(1).s("#CCCCCC").beginFill(rainbowColor).drawCircleEx(0,0,radius,pi_n*i+angle,pi_n*(i+1)+angle);
		//lineなし重なり補正
		//box.graphics.beginFill(rainbowColor).drawCircleEx(0,0,radius,pi_n*i+angle,pi_n*(i+1)+angle);

	}

	wrap.addChild(base,box);
	wrap.x=90;
	wrap.y=110;
	mainContainer.addChild(wrap);

	//---------2----------
	set_memo(200,15,"2 CreateJS drawCircleEx");

	var sides=360;//分割数
	var radius=80;
	var angle=-Math.PI/2;//角度補正12時

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=Math.PI*2/sides;//角度
	for (var i=0; i<sides; i++) {

		var rainbowColor=createjs.Graphics.getHSL(i/sides*360,100,50);//直接
		//lineなし重なり補正
		box.graphics.beginFill(rainbowColor).drawCircleEx(0,0,radius,pi_n*i+angle,pi_n*(i+1.5)+angle);

	}

	wrap.addChild(base,box);
	wrap.x=270;
	wrap.y=110;
	mainContainer.addChild(wrap);

	//---------3----------
	set_memo(380,15,"3 CreateJS drawArctoEx");

	var sides=6;//分割数
	var radius=80;
	var radius2=50;
	var angle=-Math.PI/2;//角度補正12時

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=Math.PI*2/sides;//角度
	for (var i=0; i<sides; i++) {

		var rainbowColor=createjs.Graphics.getHSL(i/sides*360,100,50);//直接
		//Fill/line
		box.graphics.ss(1).s("#FFFFFF").beginFill(rainbowColor).drawArctoEx(0,0,radius,radius2,pi_n*i+angle,pi_n*(i+1)+angle);
		//lineなし重なり補正
		//box.graphics.beginFill(rainbowColor).drawCircleEx(0,0,radius,pi_n*i+angle,pi_n*(i+1.2)+angle);

	}

	wrap.addChild(base,box);
	wrap.x=450;
	wrap.y=110;
	mainContainer.addChild(wrap);

	//---------4----------
	set_memo(550,15,"4 CreateJS drawArctoEx");

	var sides=9;//分割数
	var radius=80;
	var radius2=50;
	var angle=-Math.PI/2;//角度補正12時

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);

	//扇形
	var pi_n=Math.PI*2/sides;//角度
	for (var i=0; i<sides; i++) {

		var rainbowColor=createjs.Graphics.getHSL(i/sides*360,100,50);//直接
		//Fill/line
		box.graphics.ss(1).s("#FFFFFF").beginFill(rainbowColor).drawArctoEx(0,0,radius,radius2,pi_n*i+angle,pi_n*(i+1)+angle);
		box.shadow=shadow;//ここでのほうがきれい

	}

	wrap.addChild(base,box);
	wrap.x=630;
	wrap.y=110;
	mainContainer.addChild(wrap);

	//---------5----------
	set_memo(730,15,"5 CreateJS drawArctoEx");

	var sides=7;//分割数
	var radius=70;
	var radius2=50;
	var angle=-Math.PI/2;//角度補正12時

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	//陰影
	//弧1つで描く
	base.graphics.beginFill('rgba(0,0,0,0.5)').drawArctoEx(3,3,radius,radius2,0,Math.PI*2);
	//lineで描く
	//base.graphics.ss(20).s('rgba(0,0,0,0.5)').drawCircle(3,3,radius-10);
	//base.shadow=new createjs.Shadow("#000000",0,0,4);

	//扇形
	var pi_n=Math.PI*2/sides;//角度
	for (var i=0; i<sides; i++) {

		var rainbowColor=createjs.Graphics.getHSL(i/sides*360,100,50);//直接
		//Fill/line
		box.graphics.beginFill(rainbowColor).drawArctoEx(0,0,radius,radius2,pi_n*i+angle,pi_n*(i+1)+angle);

	}

	wrap.addChild(base,box);
	wrap.x=800;
	wrap.y=110;
	mainContainer.addChild(wrap);

	//---------6----------
	set_memo(10,215,"6 CreateJS グラフ");

	//DATA
	var data_v=[500,400,350,220,100,50];
	var color_v=["#FF69B4","#FFB6C1","#9370DB","#66CDAA","#ADD8E6","#FFD700","#F0E68C"];
	var angle_v=[];

	var sides=data_v.length;//分割数
	var radius=80;
	var angle=-Math.PI/2;//角度補正12時
	var total=0;

	//計算
	for (var i=0; i<sides; i++) {
		total +=data_v[i];
	}
	for (var i=0; i<sides; i++) {
		angle_v[i]=Math.PI*2*(data_v[i]/total);
	}

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=0;//角度
	var pi_s=0;//スタート角度
	for (var i=0; i<sides; i++) {

		pi_n +=angle_v[i];
		//Fill/line
		box.graphics.ss(1).s("#FFFFFF").beginFill(color_v[i]).drawCircleEx(0,0,radius,pi_s+angle,pi_n+angle);
		//lineなし
		//box.graphics.beginFill(color_v[i]).drawCircleEx(0,0,radius,pi_s+angle,pi_n+angle);
		pi_s +=angle_v[i];

	}

	wrap.addChild(base,box);
	wrap.x=90;
	wrap.y=310;
	mainContainer.addChild(wrap);

	//---------7----------
	set_memo(200,215,"7 CreateJS グラフ2");

	//DATA
	var data_v=[500,400,350,220,100,50];
	var color_v=["#FF69B4","#FFB6C1","#9370DB","#66CDAA","#ADD8E6","#FFD700","#F0E68C"];
	var angle_v=[];

	var sides=data_v.length;//分割数
	var radius=80;
	var angle=-Math.PI/2;//角度補正12時
	var total=0;

	//計算
	for (var i=0; i<sides; i++) {
		total +=data_v[i];
	}
	for (var i=0; i<sides; i++) {
		angle_v[i]=Math.PI*2*(data_v[i]/total);
	}

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=0;//角度
	var pi_s=0;//スタート角度
	for (var i=0; i<sides; i++) {

		pi_n +=angle_v[i];
		//lineなし
		box.graphics.beginFill(color_v[i]).drawCircleEx(0,0,radius,pi_s+angle,pi_n+angle);
		pi_s +=angle_v[i];

	}

	wrap.addChild(base,box);
	wrap.x=270;
	wrap.y=310;
	mainContainer.addChild(wrap);

	//---------8----------
	set_memo(380,215,"8 CreateJS グラフ3");

	//DATA
	var data_v=[500,400,350,220,100,50];
	var color_v=["#FF69B4","#FFB6C1","#9370DB","#66CDAA","#ADD8E6","#FFD700","#F0E68C"];
	var angle_v=[];

	var sides=data_v.length;//分割数
	var radius=80;
	var angle=0;//-Math.PI/2;//角度補正12時
	var total=0;

	//計算
	for (var i=0; i<sides; i++) {
		total +=data_v[i];
	}
	for (var i=0; i<sides; i++) {
		angle_v[i]=Math.PI*2*(data_v[i]/total);
	}

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=0;//角度
	var pi_s=0;//スタート角度
	for (var i=0; i<sides; i++) {

		pi_n +=angle_v[i];
		//Fill/line
		box.graphics.ss(1).s("#000000").beginFill(color_v[i]).drawArctoEx(0,0,radius,radius2,pi_s+angle,pi_n+angle);
		pi_s +=angle_v[i];

	}

	wrap.addChild(base,box);
	wrap.x=450;
	wrap.y=310;
	mainContainer.addChild(wrap);

	//---------9----------
	set_memo(550,215,"9 CreateJS グラフ4");

	//DATA
	var data_v=[500,400,350,220,100,50];
	var color_v=["#FF69B4","#FFB6C1","#9370DB","#66CDAA","#ADD8E6","#FFD700","#F0E68C"];
	var angle_v=[];

	var sides=data_v.length;//分割数
	var radius=80;
	var angle=-Math.PI/2;//角度補正12時
	var total=0;

	//計算
	for (var i=0; i<sides; i++) {
		total +=data_v[i];
	}
	for (var i=0; i<sides; i++) {
		angle_v[i]=Math.PI*2*(data_v[i]/total);
	}

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	base.graphics.beginFill("#FFFFFF").drawCircle(0,0,radius);
	base.shadow=shadow;

	//扇形
	var pi_n=0;//角度
	var pi_s=0;//スタート角度
	for (var i=0; i<sides; i++) {

		pi_n +=angle_v[i];
		//Fill/line
		box.graphics.ss(1).s("#FFFFFF").beginFill(color_v[i]).drawArctoEx(0,0,radius,radius2,pi_s+angle,pi_n+angle);
		//lineなし重なり補正
		//box.graphics.beginFill(rainbowColor).drawArctoEx(0,0,radius,radius2,pi_s+angle,pi_n+angle);

		box.shadow=shadow;//ここでのほうがきれい
		pi_s +=angle_v[i];

	}

	wrap.addChild(base,box);
	wrap.x=630;
	wrap.y=310;
	mainContainer.addChild(wrap);

	//---------10----------
	set_memo(730,215,"10 CreateJS グラフ5");

	//DATA
	var data_v=[500,400,350,220,100,50];
	var color_v=["#FF69B4","#FFB6C1","#9370DB","#66CDAA","#ADD8E6","#FFD700","#F0E68C"];
	var angle_v=[];

	var sides=data_v.length;//分割数
	var radius=70;
	var radius2=50;
	var angle=-Math.PI/2;//角度補正12時
	var total=0;

	//計算
	for (var i=0; i<sides; i++) {
		total +=data_v[i];
	}
	for (var i=0; i<sides; i++) {
		angle_v[i]=Math.PI*2*(data_v[i]/total);
	}

	//コンテナ収容
	var wrap=new createjs.Container();
	var box=new createjs.Shape();
	var base=new createjs.Shape();

	//陰影弧1つで描く
	base.graphics.beginFill('rgba(0,0,0,0.5)').drawArctoEx(3,3,radius,radius2,0,Math.PI*2);

	//扇形
	var pi_n=0;//角度
	var pi_s=0;//スタート角度
	for (var i=0; i<sides; i++) {

		pi_n +=angle_v[i];
		//lineなし重なり補正
		box.graphics.beginFill(color_v[i]).drawArctoEx(0,0,radius,radius2,pi_s+angle,pi_n+angle);
		pi_s +=angle_v[i];

	}

	wrap.addChild(base,box);
	wrap.x=800;
	wrap.y=310;
	mainContainer.addChild(wrap);


}

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

//Extend drawCircle
createjs.Graphics.prototype.drawCircleEx =function(x,y,radius,startAngle,endAngle) {
	//外側
	var cos=Math.cos(startAngle);
	var sin=Math.sin(startAngle);
	//中心からstart
	this.moveTo(x,y)
	.lineTo(x+radius*cos,y+radius*sin)
	.arc(x,y,radius,startAngle,endAngle);
}

//Extend draw-arcTo
createjs.Graphics.prototype.drawArctoEx=function(x,y,radius,radius2,startAngle,endAngle) {
	//外側
	var cos=Math.cos(startAngle);
	var sin=Math.sin(startAngle);
	//内側
	var cos2=Math.cos(endAngle);
	var sin2=Math.sin(endAngle);
	//内からstart
	this.moveTo(x+radius2*cos,y+radius2*sin)
	.lineTo(x+radius*cos,y+radius*sin)
	.arc(x,y,radius,startAngle,endAngle,0)
	.lineTo(x+radius2*cos2,y+radius2*sin2)
	.arc(x,y,radius2,endAngle,startAngle,1)
}

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

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

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

//START
init();

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


CSS

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


/*日本語 createJS077.css*/

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

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

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


簡単な説明


 

Graphicsクラスを拡張して 扇形、弧状図形描画


Graphicsクラスを拡張して、メソッドにする事により、通常のCreateJS Graphicsクラスの書式で記述できる。
下図はデモでのキャプチャーであるが、通常の塗り、グラデーション塗り、画像挿入などもdrawRectの形式で出来る。


[説明図]

 

1. 扇形の描画用、弧状の図形用の2種類。
2. サンプルでのarc()はMath.PIで計算するタイプですので原点は3時方向が 0 になりますから、見易い様12時方向に「左に90度」修正して描画しています。(-Math.PI/2)
3. 実際の描画はサンプルを参照ください。
4. バージョン 0.7.0 でも一応動作可能です。


Graphicsクラスを拡張

作り方は javascript 故、下記の様に非常に簡単である。処理内容はGraphicsの外形のPathである。createjs.Graphicsクラスのメソッドとして機能する。



createjs.Graphics.prototype.関数名 = function( 引数 ) { 処理内容 }

他のGraphicsクラスメソッド、drawRect()、などと同じ形式で記述できるのが便利である。


 

drawCircleEx

扇形の描画用である。開始角度、終了角を指定して描画する。元ネタと同じ関数名で、機能も同じである。他にダブルような関数があるならば名前を変更すればよい。



Graphicsクラスインスタンス.graphics.beginFill("#FF0000").drawCircleEx(x,y,半径,開始角度,終了角度);


//Extend drawCircle
createjs.Graphics.prototype.drawCircleEx =function(x,y,radius,startAngle,endAngle) {
	//外側
	var cos=Math.cos(startAngle);
	var sin=Math.sin(startAngle);
	//中心からstart
	this.moveTo(x,y)
	.lineTo(x+radius*cos,y+radius*sin)
	.arc(x,y,radius,startAngle,endAngle);
}

最後の lineTo() は自動的に原点まで描画する仕組みであるので記述していない。


● サンプル2の例
360分割したグラデーション塗りですが、グラデーションが「干渉波状」に描画されるので、本来は、(i+1)であるのですが、下記の様に、(i+1.5)として少しずらした。

もう少し加工(RadialGradient)すれば「Piker」の色サンプルとして使用できますので、機会があれば後日作って見ます。



//lineなし重なり補正
box.graphics.beginFill(rainbowColor).drawCircleEx(0,0,radius,pi_n*i+angle,pi_n*(i+1.5)+angle);

ブラウザによっても多少の表示品質は違うが、Canvasでの塗りの具合が悪い場合は少しずらせば直る場合が多い。(0.1-0.5ピクセル程度)


drawArctoEx

中心を描かない弧状の図形(扇形)描画用である。グラフの描画などに便利かと思う。 デザインなどは他のGraphicsクラス組み合わせなどで行う。CreateJSのインスタンスとしてアニメなどに加工も可能と思います。



Graphicsクラスインスタンス.graphics.beginFill("#FF0000").drawArctoEx(x,y,外半径,内半径,開始角度,終了角度);


//Extend draw-arcTo
createjs.Graphics.prototype.drawArctoEx=function(x,y,radius,radius2,startAngle,endAngle) {
	//外側
	var cos=Math.cos(startAngle);
	var sin=Math.sin(startAngle);
	//内側
	var cos2=Math.cos(endAngle);
	var sin2=Math.sin(endAngle);
	//内からstart
	this.moveTo(x+radius2*cos,y+radius2*sin)
	.lineTo(x+radius*cos,y+radius*sin)
	.arc(x,y,radius,startAngle,endAngle,0)
	.lineTo(x+radius2*cos2,y+radius2*sin2)
	.arc(x,y,radius2,endAngle,startAngle,1)
}

最後の .arc() は逆方向に描画している。


 

同じ、Graphicsクラス拡張形式の「角丸多角」および「コーナー装飾矩形」描画は前ページに掲載しています。

【参照】当方の記事: CreateJS Graphicsクラスを拡張 Round PolyStar 角丸多角形の描画 2

【参照】当方の記事: CreateJS Graphicsクラスを拡張 コーナー装飾矩形(Rect)描画



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

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


以上です。

 


[ この記事のURL ]


 

ブログ記事一覧

年別アーカイブ一覧



[1]