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);
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值