vue canvas用点绘制画框 绘制告警区域

vue yekong

vue项目需要在图片进行画框操作,用来进行重点标注,这里使用canvas来实现。

vue canvas用点绘制画框 绘制告警区域

实现代码

<template>
  <div class="test" style="background-color: burlywood; display: flex">
    <canvas
        id="myCanvas"
        ref="myCanvas"
        width="1100"
        height="500"
        @mousedown="mousedown($event)"
        @dblclick="handleDBClick"
        @mousemove="mousemove"
    >
    </canvas>
  </div>
</template>

<script>
export default {
  name: "DefectRect",
  data() {
    return {
      ctx: "", //dom节点
      canvas: null,
      tempPointArr: [], //临时存储每次点击的位置
      moveStatus: false,
      savePointArr: [], //保存每次点击的位置
    };
  },

  mounted() {
    this.canvas = this.$refs.myCanvas;
    this.ctx = this.canvas.getContext("2d");
  },

  methods: {
    // 放下鼠标
    mousedown(e) {
      clearTimeout(this.timer);
      this.moveStatus = true;
      this.timer = setTimeout(() => {
        // 每次点击,保存点击的位置
        this.tempPointArr.push([e.offsetX, e.offsetY]);
        // 绘制矩形小点
        this.ctx.fillStyle = "#FF0000";
        this.ctx.fillRect(e.offsetX - 0.5, e.offsetY - 0.5, 1, 1);
        if (this.tempPointArr.length <= 1) return;
        // 设置线宽
        this.ctx.lineWidth = 2;
        // 连线
        this.ctx.beginPath();
        this.ctx.strokeStyle = "#FF0000";
        // 找到需要连线的那个点
        this.ctx.moveTo(
            this.tempPointArr[this.tempPointArr.length - 2][0],
            this.tempPointArr[this.tempPointArr.length - 2][1]
        );
        // 画线
        this.ctx.lineTo(
            this.tempPointArr[this.tempPointArr.length - 1][0],
            this.tempPointArr[this.tempPointArr.length - 1][1]
        );
        this.ctx.stroke();
      }, 200);
    },
    // 移动鼠标,实现线跟随鼠标移动
    mousemove(e) {
      if (this.moveStatus) {
        let point = [e.offsetX, e.offsetY];
        // 先清除每次移动画出的线
        if (this.tempPointArr.length < 1) return;
        this.clear();
        // // 将点过的点之前的连线回显出来
        this.echoTempPoint(this.tempPointArr, false);
        this.ctx.fillStyle = "#FF0000";
        this.ctx.lineWidth = 2;
        // 连线
        this.ctx.beginPath();
        this.ctx.strokeStyle = "#FF0000";
        // 找到需要连线的那个点
        this.ctx.moveTo(
            this.tempPointArr[this.tempPointArr.length - 1][0],
            this.tempPointArr[this.tempPointArr.length - 1][1]
        );
        this.ctx.lineTo(point[0], point[1]);
        this.ctx.stroke();
      }
    },
    // 回显之前画的点之间的连线
    echoTempPoint(cur, status) {
      for (let i = 0; i < cur.length; i++) {
        // 绘制矩形小点
        this.ctx.fillStyle = "#FF0000";
        this.ctx.fillRect(cur[i][0] - 0.5, cur[i][1] - 0.5, 1, 1);
        this.ctx.lineWidth = 2;
        // 连线
        this.ctx.beginPath();
        this.ctx.strokeStyle = "#FF0000";

        if (i !== 0) {
          // 找到需要连线的那个点
          this.ctx.moveTo(cur[i - 1][0], cur[i - 1][1]);
          this.ctx.lineTo(cur[i][0], cur[i][1]);
        }
        // status判断回显时是否连接最后一个点和第一个点
        if (status) {
          if (i == cur.length - 1) {
            this.ctx.moveTo(cur[i][0], cur[i][1]);
            this.ctx.lineTo(cur[0][0], cur[0][1]);
          }
        }
        this.ctx.stroke();
      }
    },
    //清除画布
    clear() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    //双击保存数据,并链接最后一个点和第一个点
    handleDBClick() {
      clearTimeout(this.timer);
      if (this.tempPointArr.length <= 2) {
        this.$message.warning("至少需要3个点");
      } else {
        this.savePointArr.push(this.tempPointArr);
        this.ctx.moveTo(
            this.tempPointArr[this.tempPointArr.length - 1][0],
            this.tempPointArr[this.tempPointArr.length - 1][1]
        );
        this.ctx.lineTo(this.tempPointArr[0][0], this.tempPointArr[0][1]);
        this.ctx.stroke();
        this.moveStatus = false;
        this.tempPointArr = [];
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.test {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;
}

#myCanvas {
  position: relative;
  background: url("./assets/img.jpg") no-repeat;
  background-size: 100% 100%;
}
</style>

项目应用

vue3 数据可视化大屏 视频监控智能分析系统

喜欢