canvas根据鼠标点击生成的两点生成的直线,生成垂直于直线的两个箭头的方向,用于项目越线检测
最终效果
demo地址:https://github.com/Trap-only/Implement-line-and-area-drawing-in-canvas
已知,鼠标在canvas上点击的两个点的坐标的数组为let array=[{x:10,y50},{x:200,y:450}],根据两个点,定义这两个点生成直线的为直线L,先计算垂直于直线L的两个方向的点的坐标。
getArrowPoint(ctx, array) {
//ctx为需要绘制的canvas元素的CanvasRenderingContext2D 对象,使用它可以绘制到 Canvas 元素中。
if (array.length === 2) {
let x1 = array[0].x; // 第一个点的X
let x2 = array[1].x; // 第2个点的X
let y1 = array[0].y; // 第一个点的y
let y2 = array[1].y; // 第2个点的y
// 中点c的位置为
let c = { x: (x1 + x2) / 2, y: (y1 + y2) / 2 };
// 根据x、y的值 计算是x1-x2 还是x2-x1 以及y2-y1 还是 y1-y2
let borderX = null;
let borderY = null;
if (x1 > x2 && y2 > y1) {
borderX = x2 - x1;
borderY = y2 - y1;
} else if (x1 > x2 && y1 > y2) {
borderX = x1 - x2;
borderY = y2 - y1;
} else if (x2 > x1 && y1 > y2) {
borderX = x2 - x1;
borderY = y1 - y2;
} else {
borderX = x1 - x2;
borderY = y1 - y2;
}
// 斜边l1的长度为
let l1 = Math.sqrt(Math.pow(borderX, 2) + Math.pow(borderY, 2));
// 定义l2的默认长度为50
let l2 = 15;
let h2 = (l2 * borderX) / l1;
let s2 = Math.sqrt(Math.pow(l2, 2) - Math.pow(h2, 2));
let endX = array[1].x >= array[0].x ? s2 + c.x : c.x - s2;
let endY = c.y + h2;
let end2X = 2 * c.x - endX;
let end2Y = 2 * c.y - endY;
//drawLineArrow为 画箭头的方法
this.drawLineArrow(ctx, c.x, c.y, endX, endY, '#f00', 'A');
this.drawLineArrow(ctx, c.x, c.y, end2X, end2Y, '#f00', 'B');
}
},
已知两个方向点的坐标,画箭头,
// 画箭头
drawLineArrow(ctx, fromX, fromY, toX, toY, color, text) {
//ctx为需要绘制的canvas元素的CanvasRenderingContext2D 对象,使用它可以绘制到 Canvas 元素中。
var headlen = 10; // 自定义箭头线的长度
var theta = 45; // 自定义箭头线与直线的夹角
var arrowX, arrowY; // 箭头线终点坐标
// 计算各角度和对应的箭头终点坐标
var angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
var angle1 = ((angle + theta) * Math.PI) / 180;
var angle2 = ((angle - theta) * Math.PI) / 180;
var topX = headlen * Math.cos(angle1);
var topY = headlen * Math.sin(angle1);
var botX = headlen * Math.cos(angle2);
var botY = headlen * Math.sin(angle2);
ctx.beginPath();
// 画直线
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
arrowX = toX + topX;
arrowY = toY + topY;
// 画上边箭头线
ctx.moveTo(arrowX, arrowY);
ctx.lineTo(toX, toY);
arrowX = toX + botX;
arrowY = toY + botY;
// 画下边箭头线
ctx.lineTo(arrowX, arrowY);
ctx.strokeStyle = color;
ctx.stroke();
// 是否要显示A、B文字
ctx.font = '14px Arial bolder';
ctx.fillStyle = '#fff';
ctx.textAlign = 'left';
ctx.fillText(text, toX, toY);
}