在HTML5画布二次曲线上绘制箭头

时间:2015-01-05 11:51:18

标签: html5 canvas

我有一条二次曲线,我想在最后画一个箭头。我有这段代码:

http://jsfiddle.net/ju2jh84d/3/



var ctx = document.getElementById('arrowCanvas').getContext('2d');

var startPointX = 55;
var startPointY = 50;
var endPointX = 108;
var endPointY = 118;
ctx.strokeStyle = "rgb(0,0,255)";
ctx.lineWidth = 3;
var x = (startPointX + endPointX) / 2;
var y = (startPointY + endPointY) / 2;
var le = (endPointY - endPointY) / (startPointX - endPointX);
var angle = Math.atan(le);
var sx = Math.pow((startPointX - endPointX), 2);
var sy = Math.pow((endPointY - endPointY), 2);
var d = Math.sqrt(sx + sy) / 2;

var px = x - d * Math.sin(angle);
var py = y + d * Math.cos(angle);

var arrowAngle = Math.atan2(x - endPointX, y - endPointY);
var arrowWidth = 20;

ctx.beginPath();
ctx.moveTo(startPointX, startPointY);
ctx.quadraticCurveTo(px, py, endPointX, endPointY);
ctx.lineTo(endPointX - arrowWidth * Math.sin(arrowAngle - Math.PI / 6), endPointY - arrowWidth * Math.cos(arrowAngle - Math.PI / 6));
ctx.moveTo(endPointX, endPointY);
ctx.lineTo(endPointX - arrowWidth * Math.sin(arrowAngle + Math.PI / 6), endPointY - arrowWidth * Math.cos(arrowAngle + Math.PI / 6));
ctx.stroke();
ctx.closePath();

<canvas id="arrowCanvas"></canvas>
&#13;
&#13;
&#13;

但是虽然我可以画一个好箭头,但它没有正确倾斜。我在这段代码中做错了什么?

1 个答案:

答案 0 :(得分:2)

使用二次点对齐:

&#13;
&#13;
var ctx = document.getElementById('arrowCanvas').getContext('2d');

var startPointX = 50;
var startPointY = 10;
var endPointX = 100;
var endPointY = 120;
var quadPointX = 35;
var quadPointY = 70;

ctx.strokeStyle = "rgb(0,0,255)";
ctx.lineWidth = 3;

var arrowAngle = Math.atan2(quadPointX - endPointX, quadPointY - endPointY) + Math.PI;
var arrowWidth = 20;

ctx.beginPath();
ctx.moveTo(startPointX, startPointY);

ctx.quadraticCurveTo(quadPointX, quadPointY, endPointX, endPointY);
//ctx.lineTo(endPointX, endPointY);

ctx.moveTo(endPointX - (arrowWidth * Math.sin(arrowAngle - Math.PI / 6)), 
           endPointY - (arrowWidth * Math.cos(arrowAngle - Math.PI / 6)));

ctx.lineTo(endPointX, endPointY);

ctx.lineTo(endPointX - (arrowWidth * Math.sin(arrowAngle + Math.PI / 6)), 
           endPointY - (arrowWidth * Math.cos(arrowAngle + Math.PI / 6)));

ctx.stroke();
ctx.closePath();
&#13;
<canvas id="arrowCanvas"></canvas>
&#13;
&#13;
&#13;