vue canvas 绘制多个多边形,并且可以根据坐标数据回显

<template>
  <div class="app-container">
    <div class="d-flex j-center">
      <!--用来和鼠标进行交互操作的canvas-->
      <canvas
        id="canvas"
        width="1000px"
        height="600px"
        @mousedown="canvasDown"
        @mousemove="canvasMove"
      ></canvas>
      <!--存储已生成的点线,避免被清空-->
      <canvas id="canvasSave" width="1000px" height="600px"></canvas>
      <el-button
        class="deleteCanvas"
        id="deleteCanvas"
        type="primary"
        @click="deleteCanvasClick"
        >清空选区</el-button
      >
      <!--canvas回显-->
      <!-- <canvas class="shaped" id="quad"></canvas> -->
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      can: null,
      ctx: null,
      canSave: null,
      ctxSave: null,
      pointX: null,
      pointY: null,
      pointArr: [], //存放坐标的数组
      oIndex: -1, //判断鼠标是否移动到起始点处,-1为否,1为是
      //回显数据
      pointColorArr: [
        {
          color: "#f7b5c1",
          houseName: "601单元",
          ponitArr: [
            {
              x: 2,
              y: 133,
            },
            {
              x: 2,
              y: 401,
            },
            {
              x: 166,
              y: 401,
            },
            {
              x: 167,
              y: 134,
            },
            {
              x: 2,
              y: 133,
            },
          ],
        },
        {
          color: "#bcf7d9",
          houseName: "602单元",
          ponitArr: [
            {
              x: 442,
              y: 403,
            },
            {
              x: 440,
              y: 347,
            },
            {
              x: 581,
              y: 347,
            },
            {
              x: 584,
              y: 568,
            },
            {
              x: 5,
              y: 566,
            },
            {
              x: 3,
              y: 401,
            },
            {
              x: 442,
              y: 403,
            },
          ],
        },
      ],
    };
  },
  mounted() {
    //初始化画布对象
    this.can = document.getElementById("canvas");
    this.ctx = this.can.getContext("2d");
    this.canSave = document.getElementById("canvasSave");
    this.ctxSave = this.canSave.getContext("2d");

    this.ctx.strokeStyle = "rgba(102,168,255,1)"; //线条颜色
    this.ctx.lineWidth = 4; //线条粗细
    this.ctxSave.strokeStyle = "rgba(102,168,255,1)"; //线条颜色
    this.ctxSave.lineWidth = 4; //线条粗细
    this.init();
  },
  methods: {
    //初始化回显
    init() {
      this.pointColorArr.map((item) => {
        this.canvasFill(item.ponitArr, item.color, item.houseName);
      });
    },
    /*点击画点*/
    canvasDown(e) {
      if (e.offsetX || e.layerX) {
        this.pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
        this.pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
        var piX, piY;
        if (this.oIndex > 0 && this.pointArr.length > 0) {
          piX = this.pointArr[0].x;
          piY = this.pointArr[0].y;
          //画点
          this.makearc(
            this.ctx,
            piX,
            piY,
            this.GetRandomNum(2, 2),
            0,
            180,
            "rgba(102,168,255,1)"
          );
          this.pointArr.push({ x: piX, y: piY });
          this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
          this.saveCanvas(); //生成画布
        } else {
          piX = this.pointX;
          piY = this.pointY;
          this.makearc(
            this.ctx,
            piX,
            piY,
            this.GetRandomNum(2, 2),
            0,
            180,
            "rgba(102,168,255,1)"
          );
          this.pointArr.push({ x: piX, y: piY });
          this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
        }
      }
    },
    // 鼠标移动事件
    canvasMove(e) {
      if (e.offsetX || e.layerX) {
        this.pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
        this.pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
        var piX, piY;
        /*清空画布*/
        this.ctx.clearRect(0, 0, this.can.width, this.can.height);
        /*鼠标下跟随的圆点*/
        this.makearc(
          this.ctx,
          this.pointX,
          this.pointY,
          this.GetRandomNum(4, 4),
          0,
          180,
          "rgba(102,168,255,1)"
        );

        if (this.pointArr.length > 0) {
          if (
            this.pointX > this.pointArr[0].x - 15 &&
            this.pointX < this.pointArr[0].x + 15 &&
            this.pointY > this.pointArr[0].y - 15 &&
            this.pointY < this.pointArr[0].y + 15
          ) {
            if (this.pointArr.length > 1) {
              piX = this.pointArr[0].x;
              piY = this.pointArr[0].y;
              this.ctx.clearRect(0, 0, this.can.width, this.can.height);
              this.makearc(
                this.ctx,
                piX,
                piY,
                this.GetRandomNum(4, 4),
                0,
                180,
                "rgba(102,168,255,1)"
              );
              this.oIndex = 1;
            }
          } else {
            piX = this.pointX;
            piY = this.pointY;
            this.oIndex = -1;
          }
          /*开始绘制*/
          this.ctx.beginPath();
          this.ctx.moveTo(this.pointArr[0].x, this.pointArr[0].y);
          if (this.pointArr.length > 1) {
            for (var i = 1; i < this.pointArr.length; i++) {
              this.ctx.lineTo(this.pointArr[i].x, this.pointArr[i].y);
            }
          }
          this.ctx.lineTo(piX, piY);
          this.ctx.fillStyle = "rgba(161,195,255,1)"; //填充颜色
          this.ctx.fill(); //填充
          this.ctx.stroke(); //绘制
        }
      }
    },
    // 存储已生成的点线
    canvasSave(pointArr) {
      this.ctxSave.clearRect(0, 0, this.ctxSave.width, this.ctxSave.height);
      this.ctxSave.beginPath();
      if (pointArr.length > 1) {
        this.ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
        for (var i = 1; i < pointArr.length; i++) {
          this.ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
          this.ctxSave.fillStyle = "rgba(161,195,255,0.2)"; //填充颜色
          //this.ctxSave.fill();
          this.ctxSave.stroke(); //绘制
        }
        this.ctxSave.closePath();
      }
      console.log("存储已生成的点线", pointArr);
      //判断最后一个点重合则结束绘制
      if (pointArr.length > 1) {
        let { 0: a, [pointArr.length - 1]: b } = pointArr;
        if (a.x == b.x && b.y == b.y) {
          console.log("结束绘制");
        }
      }
    },
    //回显canvas区域
    canvasFill(pointArr, color, houseName) {
      this.ctxSave.clearRect(0, 0, this.ctxSave.width, this.ctxSave.height);
      this.ctxSave.beginPath();
      if (pointArr.length > 1) {
        this.ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
        for (var i = 1; i < pointArr.length; i++) {
          this.ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
        }
        this.ctxSave.fillStyle = `${color}B3`; //填充颜色     ${color}6B   ${color}
        this.ctxSave.fill();
        this.ctxSave.stroke(); //绘制
        this.canvasText(houseName, pointArr[0]);
      }
    },
    //绘制文字
    canvasText(text, point) {
      this.ctxSave.font = "30px Consolas"; //字体样式的属性
      this.ctxSave.textAlign = "center"; //设置文本对齐方式
      this.ctxSave.textBaseline = "middle"; //文本基线
      let textWidth = this.ctxSave.measureText(text).width;
      var canvasWidth = this.can.width;
      console.log("canvasWidth", canvasWidth);
      this.ctxSave.fillStyle = "red"; //字体颜色
      this.ctxSave.fillText(text, point.x + 70, point.y + 100); //绘制文字
      this.ctxSave.arc(point.x, point.y, 3, 0, Math.PI * 2); //基准点
    },
    /*生成画布 结束绘画*/
    saveCanvas() {
      this.ctx.clearRect(0, 0, this.can.width, this.can.height);
      this.ctxSave.closePath(); //结束路径状态,结束当前路径,如果是一个未封闭的图形,会自动将首尾相连封闭起来
      this.ctxSave.fill(); //填充
      this.ctxSave.stroke(); //绘制
      this.pointArr = [];
    },
    //清空选区
    deleteCanvasClick() {
      this.ctx.clearRect(0, 0, this.can.width, this.can.height);
      this.ctxSave.clearRect(0, 0, this.canSave.width, this.canSave.height);
      this.pointArr = [];
    },
    /*验证canvas画布是否为空函数*/
    isCanvasBlank(canvas) {
      var blank = document.createElement("canvas"); //创建一个空canvas对象
      blank.width = canvas.width;
      blank.height = canvas.height;
      return canvas.toDataURL() == blank.toDataURL(); //为空 返回true
    },
    /*canvas生成圆点*/
    GetRandomNum(Min, Max) {
      var Range = Max - Min;
      var Rand = Math.random();
      return Min + Math.round(Rand * Range);
    },
    makearc(ctx, x, y, r, s, e, color) {
      ctx.clearRect(0, 0, 199, 202); //清空画布
      ctx.beginPath();
      ctx.fillStyle = color;
      ctx.arc(x, y, r, s, e);
      ctx.fill();
    },
  },
};
</script>

<style lang="scss" scoped>
canvas {
  border: 1px solid #333;
  display: block;
}

.deleteCanvas {
  width: 100px;
  margin-left: 200px;
  margin-top: 650px;
}

#canvas {
  position: absolute;
  left: 200px;
  top: 0;
  z-index: 1;
  cursor: crosshair;
}

#canvasSave {
  position: absolute;
  left: 200px;
  top: 0;
}
#canvasSave {
  background-image: url("../../../assets/images/office.png");
  background-repeat: no-repeat;
  background-size: 600px;
}
</style>

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue中使用canvas绘制多个多边形并添加点击事件,可以按照以下步骤操作: 1. 在Vue组件中创建canvas元素,并设置其宽度和高度: ``` <template> <div> <canvas ref="canvas" width="400" height="400"></canvas> </div> </template> ``` 2. 在组件的mounted钩子函数中获取canvas元素和其上下文对象: ``` <script> export default { mounted() { this.canvas = this.$refs.canvas; this.ctx = this.canvas.getContext('2d'); } } </script> ``` 3. 在组件中定义一个数组,用于存储多边形的顶点坐标: ``` data() { return { polygons: [ [{x: 50, y: 50}, {x: 100, y: 50}, {x: 75, y: 75}], [{x: 150, y: 150}, {x: 200, y: 150}, {x: 175, y: 175}], [{x: 250, y: 250}, {x: 300, y: 250}, {x: 275, y: 275}] ] } } ``` 4. 在组件中定义一个方法,用于绘制所有的多边形: ``` methods: { drawPolygons() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.polygons.forEach(points => { this.ctx.beginPath(); this.ctx.moveTo(points[0].x, points[0].y); points.forEach(p => { this.ctx.lineTo(p.x, p.y); }); this.ctx.closePath(); this.ctx.stroke(); }); } } ``` 5. 在组件的mounted钩子函数中调用drawPolygons方法,以绘制多边形: ``` mounted() { this.canvas = this.$refs.canvas; this.ctx = this.canvas.getContext('2d'); this.drawPolygons(); } ``` 6. 在canvas元素上添加鼠标点击事件,以便在多边形上单击时触发: ``` mounted() { this.canvas = this.$refs.canvas; this.ctx = this.canvas.getContext('2d'); this.drawPolygons(); this.canvas.addEventListener('click', this.onCanvasClick); }, methods: { onCanvasClick(event) { const x = event.offsetX; const y = event.offsetY; this.polygons.forEach(points => { this.ctx.beginPath(); this.ctx.moveTo(points[0].x, points[0].y); points.forEach(p => { this.ctx.lineTo(p.x, p.y); }); this.ctx.closePath(); if (this.ctx.isPointInPath(x, y)) { console.log('clicked polygon'); // do something when polygon is clicked } }); }, // ... } ``` 这样,就可以使用Vuecanvas绘制多个多边形,并添加点击事件了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值