在 HTML5 canvas 二次曲线上绘制箭头
Drawing an arrow on an HTML5 canvas quadratic curve
我有一条二次曲线,我想在其末端画一个箭头。我有这个代码:
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>
虽然我可以画出很好的箭头,但它的角度不正确。我在这段代码中做错了什么?
使用二次点对齐:
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();
<canvas id="arrowCanvas"></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>
虽然我可以画出很好的箭头,但它的角度不正确。我在这段代码中做错了什么?
使用二次点对齐:
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();
<canvas id="arrowCanvas"></canvas>