See the Pen Bishamon-Kikko Pattern by naoyashiga (@naoyashiga) on CodePen
そのなかで「毘沙門亀甲」の紋様が目に止まり、描画することにした。
毘沙門亀甲の一つのパーツを描画する
最初は六角形隙間なく並べて、いらない辺を消去しようとしたけど、辺を消去する条件を分けるのが煩雑になりやめた。だから一つのパーツを描画する関数を作って、それの並べ方を工夫する手法をとった。
一つのパーツとは上の下手くそな絵にある、3つの六角形を合体させたものだ。赤い点線は本来、描画される線だけど、消去している。
毘沙門オブジェクトを用意
bishamon = { size: 20, xCenter: 0, yCenter: 0, lineWidth: 10, arrowWidth: 8, arrowColor: "#080808" },
プロパティ名 | 内容 |
size | 六角形の一辺の長さ |
xCenter | パーツの中心のx座標 |
yCenter | パーツの中心のy座標 |
lineWidth | 辺の太さ |
arrowWidth | パーツ内部の線の太さ |
arrowColor | パーツ内部の線の色 |
青い線がパーツ内部の線(arrow)。ピンクの点がパーツの中心だ。
bishamon.xMargin = bishamon.size * Math.cos(2 * Math.PI / 12);
xMarginというプロパティも用意する。これは緑の線の長さ。
上の六角形を描画する
//move to top side hexagon center
ctx.moveTo(bishamon.xCenter, bishamon.yCenter - bishamon.size);
上の六角形の中心に移動
//line top side hexagon for(var k = 0;k <= 6;k++){ theta = (k * 2 * Math.PI / 6) - 2 * Math.PI / 12; ctx.lineTo(bishamon.xCenter + bishamon.size * Math.cos(theta), bishamon.yCenter + bishamon.size * Math.sin(theta)); }
右下、左下の六角形も同様に、各六角形の中心に移動して描画する。
必要のない線を消去する
CanvasにclearLineはないので、clearRectするしかない。しかしこれは透明になって後から、背景色で描画しないといけないので面倒くさい。それに斜めに四角を描画するのは回転を考えないといけないので大変。だから背景色の線を重ねることにした。
//clear inside three lines
ctx.save();
ctx.beginPath();
bishamon.xCenter += bishamon.xMargin;
bishamon.yCenter -= bishamon.size / 2;
ctx.moveTo(bishamon.xCenter, bishamon.yCenter);
ctx.lineTo(bishamon.xCenter, bishamon.yCenter + bishamon.size);
ctx.moveTo(bishamon.xCenter, bishamon.yCenter);
ctx.lineTo(bishamon.xCenter - bishamon.xMargin, bishamon.yCenter - bishamon.size / 2);
ctx.moveTo(bishamon.xCenter, bishamon.yCenter);
ctx.lineTo(bishamon.xCenter + bishamon.xMargin, bishamon.yCenter - bishamon.size / 2);
ctx.strokeStyle = backgroundColor;
ctx.lineWidth = line.w * 1.5;
ctx.stroke();
ctx.closePath();
ctx.restore();
lineCapに三角はない
内部の線の先端を、六角形と同様に120度の角の三角形で描画したかった。三角形の塗りつぶしは線で囲って、fillする。上部の六角形の内部の線はそれで実装できた。しかし右下、左下は線に角度が着いており、計算がややこしく挫折したw
だから妥協案として、先端は四角にすることにした。
他の詳しい処理はソースを見てほしい。煩雑な処理が多くて、Canvasでゴリゴリ幾何の計算をするのはもう嫌だ・・・。