キャンバスに塗りつぶし円を描く部分をクラス化して利用してみます。
クラスFillArc
FillArc.js
/* FillArc.js : キャンバスの指定した位置に指定色で塗りつぶし円を描くクラス*/
class FillArc{
// コンストラクタ
constructor(x, y, r, color){
this.x = x; // x座標
this.y = y; // y座標
this.r = r; // 半径
this.color = color; // 塗りつぶし色
}
// 描画メソッド(塗りつぶし円をキャンバスに描画)
draw(){
g.fillStyle = this.color;
g.beginPath();
g.arc(this.x, this.y, this.r, 0, Math.PI*2, false);
g.fill();
}
}
ただし、クラス内の変数canvasとgはグローバル変数として以下のように宣言されることが前提です。
let canvas = null; let g = null; window.addEventListener("load", ()=>{ // キャンバス取得 canvas = document.getElementById("canvas"); g = canvas.getContext("2d"); });
実際の利用例
ソースコード補足
main.js内で3つFillArcクラスのインスタンスを生成し、指定位置に描画(drawメソッド)しています。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="FillArc.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
<title>FillArcクラス(利用例)</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>
style.css
/* style.css */
@charset "utf-8";
*{
margin: 0;
padding: 0;
}
canvas{
background-color: #eee;
}
main.js
// main.js
let canvas = null;
let g = null;
window.addEventListener("load", ()=>{
// キャンバス取得
canvas = document.getElementById("canvas");
g = canvas.getContext("2d");
// クラスFillArcを使って塗りつぶし円を描く
const fillArc1 = new FillArc(100, 100, 50, "orange");
fillArc1.draw();
const fillArc2 = new FillArc(200, 200, 100, "royalblue");
fillArc2.draw();
const fillArc3 = new FillArc(330, 330, 150, "forestgreen");
fillArc3.draw();
});
複数の塗りつぶし円を描画する
FillArcクラスを使って複数の塗りつぶし円を描画した例です。
ソースコード補足
FillArcクラスのインスタンスを繰り返し処理で100個生成し、単純にdrawメソッド実行している。
100個の塗りつぶし円は、位置、半径、色は全てランダムとした。
ランダムな色を生成するため関数getRandomColorを作成し利用している。
getRandomColor関数は以下のようなRGBカラー文字列を返す。
例)rgb(128, 53, 76)
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="FillArc.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
<title>FillArcクラス(塗りつぶし円を複数描画)</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>
style.css
/* style.css */
@charset "utf-8";
*{
margin: 0;
padding: 0;
}
canvas{
background-color: #eee;
}
main.js
// main.js
let canvas = null;
let g = null;
// ランダム色を返す関数 Ex. rgb(xxx,xxx, xxx)
function getRandomColor(){
const get256 = ()=>{ return Math.floor(Math.random()*256); }; // 0 ~ 255を返す
let [r, g, b] = [get256(), get256(), get256()]; // ランダムでRGBカラーを設定
let color = `rgb(${r}, ${g}, ${b})`; // 文字列生成 'rgb(XX, XXX, XXX)'
return color;
}
window.addEventListener("load", ()=>{
// キャンバス取得
canvas = document.getElementById("canvas");
g = canvas.getContext("2d");
// クラスFillArcを使って塗りつぶし円を描く
for(let i=0; i<100; i++){
// xy座標、半径、色をランダムで設定
const [x, y, r, color] = [
Math.floor(Math.random() * canvas.width),
Math.floor(Math.random() * canvas.height),
Math.floor(Math.random() * 60) + 10,
getRandomColor()
];
// 円を生成
const fillArc = new FillArc(x, y, r, color);
// 円を描画
fillArc.draw();
}
});
改良して円をアニメーションさせる(クラスFillArcAnim)
FillArcクラスに移動メソッド(move)を追加してアニメーションできるクラス(FillArcAnim)に改良してみます。
キャンバス端まで移動すると跳ね返る仕様です。
実行例
FillArcAnim.js
- 外部からは、updateメソッドのみで呼び出せるように、移動メソッド(move)と描画メソッド(draw)をupdateに含めている
- updateメソッドをrequestAnimationFrameにより再帰呼び出しを行うmainLoop関数で呼び出すことで、アニメーションしているように見せている
/* FillArcAnim.js : キャンバスに描いた塗りつぶし円をアニメーションさせるクラス */
class FillArcAnim{
// コンストラクタ
constructor(x, y, r, vx, vy, color){
this.x = x; // x座標
this.y = y; // y座標
this.r = r; // 半径
this.vx = vx; // x方向速度
this.vy = vy; // y方向速度
this.color = color; // 塗りつぶし色
}
// 移動メソッド
move(){
this.x += this.vx;
this.y += this.vy;
// 壁に当たったら跳ね返る(●のxy座標は中心点のため、半径を考慮)
if(this.x < 0+this.r || this.x > canvas.width-this.r){
this.vx = -this.vx;
}
if(this.y < 0+this.r || this.y > canvas.height-this.r){
this.vy = -this.vy;
}
}
// 描画メソッド
draw(){
// 円を描画
g.fillStyle = this.color;
g.beginPath();
g.arc(this.x, this.y, this.r, 0, Math.PI*2, false);
g.fill();
}
// 更新処理
update(){
this.move();
this.draw();
}
}
上記実行例に使用したソースコード
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="FillArcAnim.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
<title>FillArcAnimクラス(塗りつぶし円をアニメーション)</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>
style.css
/* style.css */
@charset "utf-8";
*{
margin: 0;
padding: 0;
}
main.js
- 起動時にFillArcAnimクラスのインスタンスを50個生成し、配列FillArcAnimsに格納。
- mainLoop関数で描画と移動を行う最後にrequestAnimationFrameでフレーム呼び出しすることで動いているように見せている。
// main.js
let canvas = null;
let g = null;
let fillArcAnims = []; // FillArcAnimクラスのインスタンス格納用配列
// 指定範囲の乱数を生成する関数(min~max)
function randInt(min, max){
return Math.floor(Math.random() * (max+1-min)+min);
}
// ランダムカラー文字列生成関数
function getRandomColor(){
const get256 = ()=>{ return Math.floor(Math.random()*256); }; // 0 ~ 255を返す
let [r, g, b] = [get256(), get256(), get256()]; // ランダムでRGBカラーを設定
let color = `rgb(${r}, ${g}, ${b})`; // 文字列生成 'rgb(XX, XXX, XXX)'
return color;
};
// 描画更新処理
function mainLoop(){
// キャンバスクリア
g.fillStyle = "#eee";
g.fillRect(0, 0, canvas.width, canvas.height);
// 円の描画位置を更新
for(let fillArcAnim of fillArcAnims){
fillArcAnim.update();
}
// フレーム毎に再帰呼び出し
requestAnimationFrame(mainLoop);
}
window.addEventListener("load", ()=>{
// キャンバス取得
canvas = document.getElementById("canvas");
g = canvas.getContext("2d");
// 円を50個生成
for(let i=0; i<50; i++){
// 半径、x方向速度、y方向速度をランダムに設定
let [r, vx, vy, color] = [
randInt(5, 70),
randInt(1, 5),
randInt(1, 5),
getRandomColor(),
];
// x座標、y座標をランダムに設定
let [x, y] = [
randInt(r, canvas.width-r),
randInt(r, canvas.height-r),
]
// 円を生成
let fillArcAnim = new FillArcAnim(x, y, r, vx, vy, color);
console.log({fillArcAnim});
// 円を配列に格納
fillArcAnims.push(fillArcAnim);
}
// 描画更新処理を開始
mainLoop();
});
コメント