canvas画箭头线

箭头线

vue+uni-app+canvas 画带箭头可拖动的线段

<template>
  <div>
    <canvas ref="canvas" class="canvas" width="600px" height="400px" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas>
  </div>
</template>

<script>
export default {
  data() {
    return {
      drawing: false,
      context: null,
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0
    };
  },
  mounted() {
    this.initializeCanvas();
  },
  methods: {
    initializeCanvas() {
      this.context = this.$refs.canvas.getContext('2d');
      this.context.strokeStyle = 'red';
      this.context.lineWidth = 2;
      this.context.strokeRect(300, 150, 10, 100);
    },
    startDrawing(event) {
      this.drawing = true;
      let rect = this.$refs.canvas.getBoundingClientRect()
      this.startX = event.clientX - rect.left;
      this.startY = event.clientY - rect.top;
    },
    draw(event) {
      if (!this.drawing) return;
      let rect = this.$refs.canvas.getBoundingClientRect()
      this.endX = event.clientX - rect.left;
      this.endY = event.clientY - rect.top;
      this.clearCanvas();
      this.drawLineArrow(this.context, this.startX, this.startY, this.endX, this.endY);
    },
    stopDrawing() {
      this.drawing = false;
      this.clearCanvas();
      this.startX = 0
      this.startY = 0
      this.endX = 0
      this.endY = 0
    },
    clearCanvas() {
      this.context.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height);

    },
    drawArrowLine(startX, startY, endX, endY) {
      this.context.beginPath();
      this.context.moveTo(startX, startY);
      this.context.lineTo(endX, endY);

      // 计算箭头的角度
      const angle = Math.atan2(endY - startY, endX - startX);

      // 绘制箭头部分
      const arrowSize = 10;
      this.context.lineTo(endX - arrowSize * Math.cos(angle - Math.PI / 6), endY - arrowSize * Math.sin(angle - Math.PI / 6));
      this.context.moveTo(endX, endY);
      this.context.lineTo(endX - arrowSize * Math.cos(angle + Math.PI / 6), endY - arrowSize * Math.sin(angle + Math.PI / 6));

      this.context.stroke();
    },
    /**
 * 
 * @param {*canvas context 对象} ctx 
 * @param {*起点横坐标} fromX 
 * @param {*起点纵坐标} fromY 
 * @param {*终点横坐标} toX 
 * @param {*终点纵坐标} toY 
 * 以下注释以终点在坐标第一象限内,且方向为右上方
 */
    drawLineArrow(ctx, fromX, fromY, toX, toY) {
      var headlen = 0.2 * 1.41 * Math.sqrt((fromX - toX) * (fromX - toX) + (fromY - toY) * (fromY - toY));//箭头头部长度
      headlen = headlen > 40 ? 40 : headlen;//40是箭头头部最大值
      var theta = 30;//自定义箭头线与直线的夹角
      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);
      var toLeft = fromX > toX;
      var toUp = fromY > toY;

      //箭头最上点
      arrowX = toX + topX;
      arrowY = toY + topY;
      //箭头下拐点
      var arrowX1 = toX + botX;
      var arrowY1 = toY + botY;
      //箭头上拐点
      var arrowX2 = toUp ? arrowX + 0.25 * Math.abs(arrowX1 - arrowX) : arrowX - 0.25 * Math.abs(arrowX1 - arrowX);
      var arrowY2 = toLeft ? arrowY - 0.25 * Math.abs(arrowY1 - arrowY) : arrowY + 0.25 * Math.abs(arrowY1 - arrowY);
      //箭头最下点 
      var arrowX3 = toUp ? arrowX + 0.75 * Math.abs(arrowX1 - arrowX) : arrowX - 0.75 * Math.abs(arrowX1 - arrowX);
      var arrowY3 = toLeft ? arrowY - 0.75 * Math.abs(arrowY1 - arrowY) : arrowY + 0.75 * Math.abs(arrowY1 - arrowY);

      ctx.beginPath();
      //起点-起点,闭合
      ctx.moveTo(fromX, fromY);
      ctx.lineTo(arrowX2, arrowY2);
      ctx.lineTo(arrowX, arrowY);
      ctx.lineTo(toX, toY);

      ctx.lineTo(arrowX1, arrowY1);
      ctx.lineTo(arrowX3, arrowY3);
      ctx.lineTo(fromX, fromY);
      ctx.closePath();
      ctx.strokeStyle = "#FB8978";
      ctx.fillStyle = "rgba(255,197,179,0.3)";
      ctx.fill();
      ctx.stroke();

    }
  }
};
</script>

<style scoped>
/* 可以添加一些样式 */
.canvas {
  /* width: 800px;
  height: 500px; */
  background: #ccc;
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是代码示例: ```html <!DOCTYPE html> <html> <head> <title>Canvas Arrow</title> <style> canvas { border: 1px solid #000; } </style> </head> <body> <canvas id="myCanvas" width="200" height="200"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); ctx.lineWidth = 2; ctx.lineCap = 'round'; // 绘制箭头 function drawArrow(x, y, length, angle) { ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + length * Math.cos(angle), y + length * Math.sin(angle)); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x + length * Math.cos(angle), y + length * Math.sin(angle)); ctx.lineTo(x + length * Math.cos(angle - Math.PI / 6), y + length * Math.sin(angle - Math.PI / 6)); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x + length * Math.cos(angle), y + length * Math.sin(angle)); ctx.lineTo(x + length * Math.cos(angle + Math.PI / 6), y + length * Math.sin(angle + Math.PI / 6)); ctx.stroke(); } // 调用绘制箭头函数 drawArrow(100, 100, 80, Math.PI / 4); </script> </body> </html> ``` 这里使用了 canvas 的 `getContext()` 方法获取上下文对象,然后设置线条宽度和线条末端形状。接着定义了绘制箭头的函数 `drawArrow()`,该函数接收箭头起点坐标、长度和角度作为参数。在函数内部,使用 `beginPath()` 开始绘制路径,然后使用 `moveTo()` 移动到起点,使用 `lineTo()` 划线箭头终点,最后使用 `stroke()` 绘制线条。绘制箭头头部时,使用了三次 `moveTo()` 和 `lineTo()` 组合,绘制三角形。最后调用 `drawArrow()` 函数即可在 canvas 中绘制箭头

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值