【JavaScript】角が丸い四角形【Canvas】

#イメージ
角丸の四角形を描画する関数です。
おまけで、吹き出しが下側に出るやつも作りました。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/8e4d9f7a-f3c4-8e89-9465-22f0ee54898b.png)
使い方はこんな感じです。

```js
const ctx = $('#myCanvas')[0].getContext("2d");
	
ctx.fillStyle = 'green';
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
	
// 角丸四角形	
fillRoundRect(ctx, 50, 100, 200, 100, 20);
strokeRoundRect(ctx, 50, 100, 200, 100, 20);
	
// 吹き出し付き角丸四角形	
fillBalloonRoundRect(ctx, 300, 100, 200, 100, 20, 30, 50, 50);
strokeBalloonRoundRect(ctx, 300, 100, 200, 100, 20, 30, 50, 50);
```
#ソース

```js
/**
 * 角が丸い四角形のパスを作成する
 * @param  {CanvasRenderingContext2D} ctx コンテキスト
 * @param  {Number} x   左上隅のX座標
 * @param  {Number} y   左上隅のY座標
 * @param  {Number} w   幅
 * @param  {Number} h   高さ
 * @param  {Number} r   半径
 */
function createRoundRectPath(ctx, x, y, w, h, r) {
	ctx.beginPath();
	ctx.moveTo(x + r, y);
	ctx.lineTo(x + w - r, y);
	ctx.arc(x + w - r, y + r, r, Math.PI * (3/2), 0, false);
	ctx.lineTo(x + w, y + h - r);
	ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * (1/2), false);
	ctx.lineTo(x + r, y + h);		
	ctx.arc(x + r, y + h - r, r, Math.PI * (1/2), Math.PI, false);
	ctx.lineTo(x, y + r);
	ctx.arc(x + r, y + r, r, Math.PI, Math.PI * (3/2), false);
	ctx.closePath();
}

/**
 * 角が丸い四角形を塗りつぶす
 * @param  {CanvasRenderingContext2D} ctx コンテキスト
 * @param  {Number} x   左上隅のX座標
 * @param  {Number} y   左上隅のY座標
 * @param  {Number} w   幅
 * @param  {Number} h   高さ
 * @param  {Number} r   半径
 */
function fillRoundRect(ctx, x, y, w, h, r) {
	createRoundRectPath(ctx, x, y, w, h, r);
	ctx.fill();
}

/**
 * 角が丸い四角形を描画
 * @param  {CanvasRenderingContext2D} ctx コンテキスト
 * @param  {Number} x   左上隅のX座標
 * @param  {Number} y   左上隅のY座標
 * @param  {Number} w   幅
 * @param  {Number} h   高さ
 * @param  {Number} r   半径
 */
function strokeRoundRect(ctx, x, y, w, h, r) {
	createRoundRectPath(ctx, x, y, w, h, r);
	ctx.stroke();		
}

/**
 * 角が丸い四角形の吹き出し(吹き出しは下側)のパスを作成する
 * @param  {CanvasRenderingContext2D} ctx コンテキスト
 * @param  {Number} x   左上隅のX座標
 * @param  {Number} y   左上隅のY座標
 * @param  {Number} w   幅
 * @param  {Number} h   高さ
 * @param  {Number} r   半径
 * @param  {Number} bl  三角形の左上隅のX座標
 * @param  {Number} br  三角形の右上隅のX座標
 * @param  {Number} bh  三角形の高さ
 */
function createBalloonRoundRectPath(ctx, x, y, w, h, r, bl, br, bh) {
	ctx.beginPath();
	ctx.moveTo(x + r, y);
	ctx.lineTo(x + w - r, y);
	ctx.arc(x + w - r, y + r, r, Math.PI * (3/2), 0, false);
	ctx.lineTo(x + w, y + h - r);
	ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * (1/2), false);		
	ctx.lineTo(x + br, y + h);
	ctx.lineTo(x + (br + bl) / 2, y + h + bh);
	ctx.lineTo(x + bl, y + h);
	ctx.lineTo(x + r, y + h);
	ctx.arc(x + r, y + h - r, r, Math.PI * (1/2), Math.PI, false);
	ctx.lineTo(x, y + r);
	ctx.arc(x + r, y + r, r, Math.PI, Math.PI * (3/2), false);
	ctx.closePath();
}

/**
 * 角が丸い四角形の吹き出し(吹き出しは下側)を塗りつぶす
 * @param  {CanvasRenderingContext2D} ctx コンテキスト
 * @param  {Number} x   左上隅のX座標
 * @param  {Number} y   左上隅のY座標
 * @param  {Number} w   幅
 * @param  {Number} h   高さ
 * @param  {Number} r   半径
 * @param  {Number} bl  三角形の左上隅のX座標
 * @param  {Number} br  三角形の右上隅のX座標
 * @param  {Number} bh  三角形の高さ
 */
function fillBalloonRoundRect(ctx, x, y, w, h, r, bl, br, bh) {
	createBalloonRoundRectPath(ctx, x, y, w, h, r, bl, br, bh);
	ctx.fill();		
}

/**
 * 角が丸い四角形の吹き出し(吹き出しは下側)を描画する
 * @param  {CanvasRenderingContext2D} ctx コンテキスト
 * @param  {Number} x   左上隅のX座標
 * @param  {Number} y   左上隅のY座標
 * @param  {Number} w   幅
 * @param  {Number} h   高さ
 * @param  {Number} r   半径
 * @param  {Number} bl  三角形の左上隅のX座標
 * @param  {Number} br  三角形の右上隅のX座標
 * @param  {Number} bh  三角形の高さ
 */
function strokeBalloonRoundRect(ctx, x, y, w, h, r, bl, br, bh) {
	createBalloonRoundRectPath(ctx, x, y, w, h, r, bl, br, bh);
	ctx.stroke();		
}
```