canvasで実線を引くにはlineTo()とstroke()を使用すればよいですが、点線の場合はメソッドが用意されていません。そのため、点線を引きたい場合にはそのためのプログラムを独自に書く必要が出てきます。今回はその一例をご紹介します。
まずは完成形です。
See the Pen stroke dotted line in canvas by ykob (@ykob) on CodePen.
このような点線を描画するために必要な要素は何でしょうか。
またそれらの要素を使って、どのようなプログラムを書くべきでしょうか。
lineTo()の代わりにピタゴラスの定理、アークタンジェント、三角関数を使う
実線にしろ点線にしろ、始点と終点を決めるのには変わりありません。実線を引く場合はメソッドが用意されているので、始点と終点の座標だけ用意すれば足りますが、点線を引く場合はほかに以下のものを用意してあげる必要があります。
- 始点(p1)、終点(p2)間の距離(d)
- 始点(p1)を中心とした、終点(p2)までの角度(rad)
- 点線の間隔
点線の間隔は任意で決めれば済みますが、それ以外の2点についてはそれぞれ以下の方法で求めることができます。
始点(p1)、終点(p2)間の距離(d)を求める
距離を求めるには、ピタゴラスの定理を使用します。
JavaScriptでは以下のように書くことができます。
d = Math.sqrt(Math.pow(p2x - p1x, 2) + Math.pow(p2y - p1y, 2));
始点(p1)を中心とした、終点(p2)までの角度(rad)を求める
角度を求めるには、アークタンジェントを使います。 JavaScriptでは以下のように書くことができます。
rad = Math.atan2(p2y - p1y, p2x - p1x);
求めた距離、角度と三角関数を使って、点線を描画する
距離を点線の間隔×2で割ると、点線の点の数が算出できます。
点の数がわかれば、あとはその数の分だけ線を引く繰り返し処理を行うだけです。
点線というのは、一定の長さの実線が一定の間隔を空けて繰り返し描画されるという風にも表現できますから、canvasでもそのように書けばよいです。角度と三角関数、間隔、点線の番号を使って計算をしますが、このなかでは三角関数がもっとも難しいでしょうか。三角関数を使った座標の計算については別の記事で既に解説をしていますので、今回は具体的な例を以下に挙げてしまいます。
var strokeDottedLine = function(p1x, p1y, p2x, p2y) {
var d = Math.sqrt(Math.pow(p2x - p1x, 2) + Math.pow(p2y - p1y, 2));
var rad = Math.atan2(p2y - p1y, p2x - p1x);
var space = 10;
var dotted = Math.round(d / space / 2);
for (var i = 0; i < dotted; i++) {
var p3x = Math.cos(rad) * space * (i * 2) + p1x;
var p3y = Math.sin(rad) * space * (i * 2) + p1y;
var p4x = Math.cos(rad) * space * (i * 2 + 1) + p1x;
var p4y = Math.sin(rad) * space * (i * 2 + 1) + p1y;
ctx.beginPath();
ctx.moveTo(p3x, p3y);
ctx.lineTo(p4x, p4y);
ctx.stroke();
ctx.closePath();
}
};
このように関数化しておけば、始点と終点の座標を引数に指定するだけで、先に挙げたデモのような点線の描画を使いまわすことができます。