文章目录
- 直线/弧线 箭头
直线/弧线 箭头
// startX,startY 起始坐标
// endX,endY 结束坐标
// radian 圆弧角度,取值[0,PI]; 0表示画直线箭头,否则画圆弧箭头
CanvasRenderingContext2D.prototype.drawArrow = function(startX,startY,endX,endY,radian,options){if(startX===endX&&startY===endY){return;}options = options||{'leg':10,'up':true,'lineCap':'round','lineWidth':3,'strokeStyle':'red'}// options.up 弧线是否向上拱// 备份线条属性const {lineCap:defaultLineCap,lineWidth:defaultLineWidth,strokeStyle:defaultStrokeStyle} = this;this.lineCap = options.lineCap;this.lineWidth = options.lineWidth;this.strokeStyle = options.strokeStylethis.beginPath();let rotatedRadian;if(!radian){ // radian = 0, 画直线// 画长直线this.moveTo(startX,startY);this.lineTo(endX,endY);// 计算以结束点为中心点的旋转角度(atan只能返回-PI/2,PI/2,我们需要0,PI,使用atan2)rotatedRadian = (Math.atan2((startY-endY),(startX-endX)));}else{// 画圆弧// 计算圆弧圆心,半径let [middlePointX,middlePointY] = [(startX+endX)/2,(startY+endY)/2]let rotatedRadian1 if(options.up){rotatedRadian1 = (Math.atan2((endY-startY),(endX-startX)))+Math.PI/2;}else{rotatedRadian1 = (Math.atan2((startY-endY),(startX-endX)))+Math.PI/2;}let len = Math.atan(radian/2)*Math.sqrt(Math.pow(middlePointX-endX,2)+Math.pow(middlePointY-endY,2));let [radiusPointX,radiusPointY] = [middlePointX + len*Math.cos(rotatedRadian1),middlePointY + len*Math.sin(rotatedRadian1)]let radius = Math.sqrt(Math.pow(radiusPointX-endX,2)+Math.pow(radiusPointY-endY,2));// 画弧线this.arc(radiusPointX,radiusPointY,radius,Math.atan2((startY-radiusPointY),(startX-radiusPointX)),Math.atan2((endY-radiusPointY),(endX-radiusPointX)),!options.up)if(options.up){rotatedRadian = (Math.atan2((endY-radiusPointY),(endX-radiusPointX)))-Math.PI/2;}else{rotatedRadian = (Math.atan2((radiusPointY-endY),(radiusPointX-endX)))-Math.PI/2;}}// 计算2个箭头线的端点let x1 = endX + options.leg * Math.cos(rotatedRadian-Math.PI/4);let y1 = endY + options.leg * Math.sin(rotatedRadian-Math.PI/4);let x2 = endX + options.leg * Math.cos(rotatedRadian+Math.PI/4);let y2 = endY + options.leg * Math.sin(rotatedRadian+Math.PI/4);// 画2个箭头线this.moveTo(x1,y1);this.lineTo(endX,endY);this.moveTo(x2,y2);this.lineTo(endX,endY);this.stroke();// 恢复线条属性this.lineCap = defaultLineCapthis.lineWidth = defaultLineWidth;this.strokeStyle = defaultStrokeStyle}
context.drawArrow(0,0,220,120,Math.PI*3)
context.drawArrow(0,0,120,80,Math.PI/4)
context.drawArrow(60,130,60,20)
context.drawArrow(257,50,50,133)
此文将持续更新…