javascriptで直線を描画(非canvas)

javascriptで線を描画したい。
斜めにも描画したい。
しかし、諸事情でcanvasは使えない。
そんな時、どうしますか?


1pxのDivを繋げて線を描画する手法もありますが、
なんかギザギザになるし・・・。


で、考えたのですがborder-topを指定したDivをrotateさせれば
斜めの線も引けるんじゃない?


点1(x1, y1)と点2(x2, y2)の2点に線を描画しようと考える場合、
まず線の長さは、

Math.sqrt(Math.pow((param.x1 - param.x2) ,2) + Math.pow((param.y1 - param.y2) ,2))

で求められます。

次に、2点間の角度ですが逆三角関数を使用することで求められます。

Math.atan(高さ / 底辺)

求められる数値はラジアンなので、℃に変換すれば、
CSS3のtransform(deg)
で傾きを表現できます。
transform-origin
で回転軸を左端にすることを忘れずに!!

では、まずcss

.line{
    position: absolute;
    border-top: solid 1px #FF4981;
    -moz-transform-origin:0% 0%;
    -webkit-transform-origin:0% 0%;
    transform-origin:0% 0%;
    float: left;
}

次にjs

function DrawLine(params) {

	var param = jQuery.extend({
	      x1: 0
	    , y1: 0
	    , x2: 0
	    , y2: 0
	    , line_style: "solid"
	    , line_color: "#000"
	    , line_width: "1px"
	    , parent: $("body")
	    , callback: function(){}
	}, params);

	var w = Math.sqrt(Math.pow((param.x1 - param.x2) ,2) + Math.pow((param.y1 - param.y2) ,2));	// 線の長さを算出する(2点間の距離を算出する)
	var base = Math.max(param.x1, param.x2) - Math.min(param.x1, param.x2); // 底辺長を算出する(aTanの算出のため)
	var tall = Math.max(param.y1, param.y2) - Math.min(param.y1, param.y2); // 高さを算出する(aTanの算出のため)
	var aTan = Math.atan(tall / base); // 逆三角関数で tanのθを算出する
	var deg = aTan * 180 / Math.PI; // rad => degrees
	deg = params.y1 > param.y2 ? 0 - deg: deg; // 回転方向

	var line = $("<div></div>")
			   .addClass("line")
			   .css({
			   	     "left": param.x1, 
			   	     "top": params.y1,
			   	     "width": w, 
			   		 "transform": "rotate(" + deg + "deg)",
			   		 "-webkit-transform": "rotate(" + deg + "deg)",
			   		 "border-top-style": param.line_style,
			   		 "border-top-color": param.line_color,
			   		 "border-top-width": param.line_width,
			   	});
	$(param.parent).append(line);
}

呼出し側

<script type="text/javascript">
$(document).ready(function()
{
	DrawLine({
		x1: 50,
		y1: 50,
		x2: 190,
		y2: 120,
	});

	DrawLine({
		x1: 150,
		y1: 250,
		x2: 390,
		y2: 120,
		line_color: "#999",
		line_width: "3px",
	});

});
</script>