zhangzengfei
2022-09-23 60df1fd19c0b4bec51c05135852bee1c440499f6
src/components/canvas/Dialog.vue
@@ -15,9 +15,9 @@
        <canvas
          id="canvasDialog"
          ref="canvasDialog"
          width="1042"
          height="586"
          :style="`position:static;background:url(${snapshot_url}) 0% 0%/1042px 586px no-repeat;`"
          width="960"
          height="540"
          :style="`position:static;background:url(${snapshot_url}) 0% 0%/960px 540px no-repeat;`"
        ></canvas>
        <p
          style="
@@ -35,11 +35,7 @@
      </div>
      <div class="control">
        <el-tooltip
          content="切换到此状态后可选中已画图形"
          placement="left"
          popper-class="atooltip"
        >
        <el-tooltip content="切换到此状态后可选中已画图形" placement="left" popper-class="atooltip">
          <el-button
            class="btn"
            @click="changeType('0')"
@@ -49,45 +45,18 @@
            <i class="iconfont">&#xe636;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="直线"
          placement="left"
          popper-class="atooltip"
          :class="{ selectedBtn: type == '1' }"
        >
          <el-button
            class="btn"
            @click="changeType('1')"
            :disabled="disableLine"
          >
        <el-tooltip content="直线" placement="left" popper-class="atooltip" :class="{ selectedBtn: type == '1' }">
          <el-button class="btn" @click="changeType('1')" :disabled="disableLine">
            <i class="iconfont">&#xe634;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="矩形"
          placement="left"
          popper-class="atooltip"
          :class="{ selectedBtn: type == '2' }"
        >
          <el-button
            class="btn"
            @click="changeType('2')"
            :disabled="disableRect"
          >
        <el-tooltip content="矩形" placement="left" popper-class="atooltip" :class="{ selectedBtn: type == '2' }">
          <el-button class="btn" @click="changeType('2')" :disabled="disableRect">
            <i class="iconfont">&#xe63a;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="箭头"
          placement="left"
          popper-class="atooltip"
          :class="{ selectedBtn: type == '4' }"
        >
          <el-button
            class="btn"
            @click="changeType('4')"
            :disabled="disableArrow"
          >
        <el-tooltip content="箭头" placement="left" popper-class="atooltip" :class="{ selectedBtn: type == '4' }">
          <el-button class="btn" @click="changeType('4')" :disabled="disableArrow">
            <i class="iconfont">&#xe635;</i>
          </el-button>
        </el-tooltip>
@@ -97,52 +66,27 @@
          popper-class="atooltip"
          :class="{ selectedBtn: type == '5' }"
        >
          <el-button
            @click="changeType('5')"
            class="btn"
            :disabled="disablePolygon"
          >
          <el-button @click="changeType('5')" class="btn" :disabled="disablePolygon">
            <i class="iconfont">&#xe633;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="选中图形再编辑重绘,重绘的图形保留之前的名称"
          placement="left"
          popper-class="atooltip"
        >
        <el-tooltip content="选中图形再编辑重绘,重绘的图形保留之前的名称" placement="left" popper-class="atooltip">
          <el-button class="btn" @click="edit()" :disabled="disableSelect">
            <i class="iconfont">&#xe638;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="先选中图形,再删除"
          placement="left"
          popper-class="atooltip"
        >
        <el-tooltip content="先选中图形,再删除" placement="left" popper-class="atooltip">
          <el-button class="btn" @click="del()" :disabled="disableSelect">
            <i class="iconfont">&#xe63b;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="清空所有已画图形,此操作不可撤销"
          placement="left"
          popper-class="atooltip"
        >
        <el-tooltip content="清空所有已画图形,此操作不可撤销" placement="left" popper-class="atooltip">
          <el-button class="btn" @click="clear()" :disabled="disableSelect">
            <i class="iconfont">&#xe637;</i>
          </el-button>
        </el-tooltip>
        <el-tooltip
          content="撤销上一步操作"
          placement="left"
          popper-class="atooltip"
        >
          <el-button
            class="btn"
            @click="del()"
            :disabled="disableSelect"
            style="border: 0px"
          >
        <el-tooltip content="撤销上一步操作" placement="left" popper-class="atooltip">
          <el-button class="btn" @click="del()" :disabled="disableSelect" style="border: 0px">
            <i class="iconfont">&#xe639;</i>
          </el-button>
          <!-- <span
@@ -184,7 +128,7 @@
        line: [],
        rect: [], // {id:'uuid', name: '矩形1', location: [{ x: 20, y: 30 }, { x: 20, y: 60 }, { x: 100, y: 60 }, { x: 100, y: 30 }] }
        arrow: [],
        polygon: [],
        polygon: []
      },
      // canvasData: this.canvasDataToChild, // 最终输出的画布坐标数据
      originX: null, // 当前点击点x
@@ -196,46 +140,46 @@
      c: null,
      ctx: null,
      inputWidth: 80,
      oldName: "", // 用来暂存更改之前的remarksName,方便放进撤销队列里
    };
      oldName: "" // 用来暂存更改之前的remarksName,方便放进撤销队列里
    }
  },
  mounted() {
    this.init();
    this.init()
  },
  watch: {
    delCursor: {
      handler(newVal, oldVal) {
        if (newVal.remarksName) {
          this.inputWidth = newVal.remarksName.length * 20;
          this.inputWidth = newVal.remarksName.length * 20
        }
        this.oldName = oldVal.remarksName;
        this.oldName = oldVal.remarksName
      },
      deep: true,
      deep: true
    },
    snapshot_url: {
      handler(newVal, oldVal) {
        if (newVal !== oldVal) {
          // console.log(newVal, 'canvasDialog')
        }
      },
      }
    },
    canvasDataToChild: {
      handler(newVal, oldVal) {
        // console.log(newVal, '打开绘制后接收到的数据')
        this.canvasHistory.length = 0;
        this.step = -1;
        this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
        this.clickSelect(this.canvasData);
        this.indexInit();
        this.canvasHistory.length = 0
        this.step = -1
        this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild))
        this.clickSelect(this.canvasData)
        this.indexInit()
        // 先录个快照,不然一画线就没了
        this.step++;
        this.step++
        this.canvasHistory.push({
          type: 0,
          src: this.c.toDataURL("image/png"),
        });
          src: this.c.toDataURL("image/png")
        })
      },
      deep: true,
    },
      deep: true
    }
    // canvasDataToChild: function(newVal, oldVal) {
    //   this.init()
    // }
@@ -244,371 +188,363 @@
    // 初始化函数
    init() {
      //this.c = document.querySelector("#canvasDialog");
      this.c = this.$refs["canvasDialog"];
      this.ctx = this.c.getContext("2d");
      this.drawCanvasInit();
      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
      this.clickSelect(this.canvasData);
      this.indexInit();
      this.c = this.$refs["canvasDialog"]
      this.ctx = this.c.getContext("2d")
      this.drawCanvasInit()
      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild))
      this.clickSelect(this.canvasData)
      this.indexInit()
      // 先录个快照,不然一画线就没了
      this.step++;
      this.step++
      this.canvasHistory.push({
        type: 0,
        src: this.c.toDataURL("image/png"),
      });
      this.delCursor = { type: -1, index: -1, remarksName: "", id: "" };
        src: this.c.toDataURL("image/png")
      })
      this.delCursor = { type: -1, index: -1, remarksName: "", id: "" }
      console.log("画布初始化");
      console.log("画布初始化")
    },
    // 取消画布清除状态函数
    cancel() {
      this.changeType("0");
      this.undisabled();
      this.changeType("0")
      this.undisabled()
      //this.delCursor = {}
      this.delCursor = { type: -1, index: -1, remarksName: "", id: "" };
      this.canvasHistory.length = 0;
      this.step = -1;
      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
      this.clickSelect(this.canvasData);
      this.indexInit();
      this.delCursor = { type: -1, index: -1, remarksName: "", id: "" }
      this.canvasHistory.length = 0
      this.step = -1
      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild))
      this.clickSelect(this.canvasData)
      this.indexInit()
      // 先录个快照,不然一画线就没了
      this.step++;
      this.step++
      this.canvasHistory.push({
        type: 0,
        src: this.c.toDataURL("image/png"),
      });
        src: this.c.toDataURL("image/png")
      })
    },
    // 主监听流程
    drawCanvasInit() {
      window.addEventListener("keydown", (e) => {
        let keyID = e.keyCode ? e.keyCode : e.which;
        let keyID = e.keyCode ? e.keyCode : e.which
        if (keyID === 82) {
          // r键
          this.undo();
          this.undo()
        }
      });
      })
      this.c.addEventListener("mousedown", (e) => {
        if (this.type !== "0") {
          this.flag = true;
          this.originX = e.offsetX; // 鼠标落下时的X
          this.originY = e.offsetY; // 鼠标落下时的Y
          this.flag = true
          this.originX = e.offsetX // 鼠标落下时的X
          this.originY = e.offsetY // 鼠标落下时的Y
          if (this.type === "5") {
            // 绘制多边形
            this.points.push({
              x: this.originX,
              y: this.originY,
            });
              y: this.originY
            })
          }
        } else {
          this.clickSelect(e);
          this.clickSelect(e)
        }
      });
      })
      this.c.addEventListener("mousemove", (e) => {
        switch (this.type) {
          case "1":
            this.drawLine(e);
            break;
            this.drawLine(e)
            break
          case "2":
            this.drawRect(e);
            break;
            this.drawRect(e)
            break
          case "4":
            this.drawArrow(e);
            break;
            this.drawArrow(e)
            break
          case "5":
            this.drawPolygon(e);
            break;
            this.drawPolygon(e)
            break
        }
      });
      })
      this.c.addEventListener("mouseup", (e) => {
        switch (this.type) {
          case "1":
            // 直线
            this.lineMouseUp(e);
            break;
            this.lineMouseUp(e)
            break
          case "2":
            // 矩形
            this.rectMouseUp(e);
            break;
            this.rectMouseUp(e)
            break
          case "4":
            // 箭头
            this.arrowMouseUp(e);
            break;
            this.arrowMouseUp(e)
            break
        }
      });
      })
      this.c.addEventListener("dblclick", (e) => {
        if (this.type === "5") {
          // 绘制多边形
          this.polygonDblclick(e);
          this.polygonDblclick(e)
        }
      });
      })
    },
    // 清除画布函数
    clear() {
      // console.log("清除");
      this.ctx.clearRect(0, 0, this.c.width, this.c.height);
      this.ctx.clearRect(0, 0, this.c.width, this.c.height)
      // 清空保存的状态
      this.url = "";
      this.canvasData.line.length = 0;
      this.canvasData.rect.length = 0;
      this.canvasData.arrow.length = 0;
      this.canvasData.polygon.length = 0;
      this.canvasHistory.length = 0;
      this.url = ""
      this.canvasData.line.length = 0
      this.canvasData.rect.length = 0
      this.canvasData.arrow.length = 0
      this.canvasData.polygon.length = 0
      this.canvasHistory.length = 0
      this.indexInit();
      this.freedEdit();
      this.delCursor = {};
      this.step = -1;
      this.indexInit()
      this.freedEdit()
      this.delCursor = {}
      this.step = -1
    },
    // 修改图形名称
    changeName() {
      if (this.delCursor.remarksName.length <= 6) {
        switch (this.delCursor.type) {
          case "1":
            this.oldName = this.canvasData.line[this.delCursor.index].name;
            this.canvasData.line[this.delCursor.index].name =
              this.delCursor.remarksName;
            break;
            this.oldName = this.canvasData.line[this.delCursor.index].name
            this.canvasData.line[this.delCursor.index].name = this.delCursor.remarksName
            break
          case "2":
            this.oldName = this.canvasData.rect[this.delCursor.index].name;
            this.canvasData.rect[this.delCursor.index].name =
              this.delCursor.remarksName;
            break;
            this.oldName = this.canvasData.rect[this.delCursor.index].name
            this.canvasData.rect[this.delCursor.index].name = this.delCursor.remarksName
            break
          case "4":
            this.oldName = this.canvasData.arrow[this.delCursor.index].name;
            this.canvasData.arrow[this.delCursor.index].name =
              this.delCursor.remarksName;
            break;
            this.oldName = this.canvasData.arrow[this.delCursor.index].name
            this.canvasData.arrow[this.delCursor.index].name = this.delCursor.remarksName
            break
          case "5":
            this.oldName = this.canvasData.polygon[this.delCursor.index].name;
            this.canvasData.polygon[this.delCursor.index].name =
              this.delCursor.remarksName;
            break;
            this.oldName = this.canvasData.polygon[this.delCursor.index].name
            this.canvasData.polygon[this.delCursor.index].name = this.delCursor.remarksName
            break
        }
        this.clickSelect();
        this.step++;
        this.clickSelect()
        this.step++
        this.canvasHistory.push({
          type: this.delCursor.type,
          src: this.c.toDataURL("image/png"),
          index: this.delCursor.index,
          name: this.oldName,
        });
          name: this.oldName
        })
      } else {
        this.$notify({
          type: "warning",
          message: "命名长度不能超过6个字!",
        });
          message: "命名长度不能超过6个字!"
        })
        switch (this.delCursor.type) {
          case "1":
            this.delCursor.remarksName =
              this.canvasData.line[this.delCursor.index].name;
            break;
            this.delCursor.remarksName = this.canvasData.line[this.delCursor.index].name
            break
          case "2":
            this.delCursor.remarksName =
              this.canvasData.rect[this.delCursor.index].name;
            break;
            this.delCursor.remarksName = this.canvasData.rect[this.delCursor.index].name
            break
          case "4":
            this.delCursor.remarksName =
              this.canvasData.arrow[this.delCursor.index].name;
            break;
            this.delCursor.remarksName = this.canvasData.arrow[this.delCursor.index].name
            break
          case "5":
            this.delCursor.remarksName =
              this.canvasData.polygon[this.delCursor.indexhhhhhhhhhhh].name;
            break;
            this.delCursor.remarksName = this.canvasData.polygon[this.delCursor.indexhhhhhhhhhhh].name
            break
        }
      }
    },
    // 左上角输入框失去焦点后保存一张快照以作撤销之用
    saveUrl() {
      // console.log("保存一张快照");
      let delEle = {};
      this.clickSelect();
      this.step++;
      let delEle = {}
      this.clickSelect()
      this.step++
      this.canvasHistory.push({
        type: this.delCursor.type,
        src: this.c.toDataURL("image/png"),
        index: this.delCursor.index,
        data: delEle,
      });
        data: delEle
      })
    },
    // 删除元素
    del() {
      let delEle = {};
      let delEle = {}
      switch (this.delCursor.type) {
        case "1":
          delEle = this.canvasData.line[this.delCursor.index];
          this.canvasData.line.splice(this.delCursor.index, 1);
          break;
          delEle = this.canvasData.line[this.delCursor.index]
          this.canvasData.line.splice(this.delCursor.index, 1)
          break
        case "2":
          delEle = this.canvasData.rect[this.delCursor.index];
          this.canvasData.rect.splice(this.delCursor.index, 1);
          break;
          delEle = this.canvasData.rect[this.delCursor.index]
          this.canvasData.rect.splice(this.delCursor.index, 1)
          break
        case "4":
          delEle = this.canvasData.arrow[this.delCursor.index];
          this.canvasData.arrow.splice(this.delCursor.index, 1);
          break;
          delEle = this.canvasData.arrow[this.delCursor.index]
          this.canvasData.arrow.splice(this.delCursor.index, 1)
          break
        case "5":
          delEle = this.canvasData.polygon[this.delCursor.index];
          this.canvasData.polygon.splice(this.delCursor.index, 1);
          break;
          delEle = this.canvasData.polygon[this.delCursor.index]
          this.canvasData.polygon.splice(this.delCursor.index, 1)
          break
      }
      this.clickSelect();
      this.step++;
      this.clickSelect()
      this.step++
      this.canvasHistory.push({
        type: this.delCursor.type,
        src: this.c.toDataURL("image/png"),
        index: this.delCursor.index,
        deleteLength: 0, // 删除的话deleteLength为0
        data: delEle,
      });
        data: delEle
      })
      // console.log(this.canvasHistory, "删除之后的撤销队列");
    },
    edit() {
      let delEle = {};
      let delEle = {}
      switch (this.delCursor.type) {
        case "1":
          delEle = {
            id: this.canvasData.line[this.delCursor.index].id,
            name: this.canvasData.line[this.delCursor.index].name,
            location: this.canvasData.line[this.delCursor.index].location,
          };
            location: this.canvasData.line[this.delCursor.index].location
          }
          // this.canvasData.line.splice(this.delCursor.index, 1);
          this.canvasData.line[this.delCursor.index].location = [
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
          ];
          break;
            { x: delEle.location[0].x, y: delEle.location[0].y }
          ]
          break
        case "2":
          delEle = {
            id: this.canvasData.rect[this.delCursor.index].id,
            name: this.canvasData.rect[this.delCursor.index].name,
            location: this.canvasData.rect[this.delCursor.index].location,
          };
            location: this.canvasData.rect[this.delCursor.index].location
          }
          // this.canvasData.rect.splice(this.delCursor.index, 1);
          this.canvasData.rect[this.delCursor.index].location = [
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
          ];
          break;
            { x: delEle.location[0].x, y: delEle.location[0].y }
          ]
          break
        case "4":
          delEle = {
            id: this.canvasData.arrow[this.delCursor.index].id,
            name: this.canvasData.arrow[this.delCursor.index].name,
            location: this.canvasData.arrow[this.delCursor.index].location,
          };
            location: this.canvasData.arrow[this.delCursor.index].location
          }
          // this.canvasData.arrow.splice(this.delCursor.index, 1);
          this.canvasData.arrow[this.delCursor.index].location = [
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
          ];
          break;
            { x: delEle.location[0].x, y: delEle.location[0].y }
          ]
          break
        case "5":
          delEle = {
            id: this.canvasData.polygon[this.delCursor.index].id,
            name: this.canvasData.polygon[this.delCursor.index].name,
            location: this.canvasData.polygon[this.delCursor.index].location,
          };
            location: this.canvasData.polygon[this.delCursor.index].location
          }
          // this.canvasData.polygon.splice(this.delCursor.index, 1);
          this.canvasData.polygon[this.delCursor.index].location = [
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
            { x: delEle.location[0].x, y: delEle.location[0].y },
          ];
          break;
            { x: delEle.location[0].x, y: delEle.location[0].y }
          ]
          break
      }
      this.clickSelect();
      this.step++;
      this.clickSelect()
      this.step++
      this.canvasHistory.push({
        type: this.delCursor.type,
        src: this.c.toDataURL("image/png"),
        index: this.delCursor.index,
        deleteLength: 1, // 编辑的话deleteLength为1
        data: delEle,
      });
        data: delEle
      })
      this.editObj = {
        id: this.delCursor.id,
        type: this.delCursor.type,
        index: this.delCursor.index,
        remarksName: this.delCursor.remarksName,
      };
      this.disabledOthers(this.delCursor.type);
        remarksName: this.delCursor.remarksName
      }
      this.disabledOthers(this.delCursor.type)
      // 切换当前状态
      this.changeType(this.delCursor.type);
      this.changeType(this.delCursor.type)
      this.$notify({
        type: "warning",
        message: "已擦除旧的区域,请直接绘制区域",
      });
        message: "已擦除旧的区域,请直接绘制区域"
      })
    },
    // 点击选中变色 将当前页面所有路径重绘判断当前鼠标的坐标在哪个图形内 如果不传坐标参数就是回显的方法
    clickSelect(e) {
      this.ctx.clearRect(0, 0, this.c.width, this.c.height);
      this.ctx.clearRect(0, 0, this.c.width, this.c.height)
      // console.log("当前数据:",this.canvasData)
      this.ctx.lineWidth = "2";
      let _this = this; // 集合中遍历需要将this转存一下使用
      _this.canvasData.line.forEach(function (v, i) {
        _this.ctx.strokeStyle = "yellow";
        _this.ctx.beginPath();
        _this.ctx.moveTo(v.location[0].x, v.location[0].y);
        _this.ctx.lineTo(v.location[1].x, v.location[1].y);
        _this.ctx.stroke();
        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
        _this.c.style.cursor = "pointer";
      this.ctx.lineWidth = "2"
      let _this = this // 集合中遍历需要将this转存一下使用
      _this.canvasData.line.forEach(function(v, i) {
        _this.ctx.strokeStyle = "yellow"
        _this.ctx.beginPath()
        _this.ctx.moveTo(v.location[0].x, v.location[0].y)
        _this.ctx.lineTo(v.location[1].x, v.location[1].y)
        _this.ctx.stroke()
        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false)
        _this.c.style.cursor = "pointer"
        if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
          // 如果传入了事件坐标,就用isPointInStroke判断一下
          // 如果当前环境覆盖了该坐标,就将图形的index放到数组里
          // 当鼠标移入之后将当前的模式切换为选中模式
          _this.type = "0";
          _this.delCursor.type = "1";
          _this.delCursor.index = i;
          _this.delCursor.remarksName = v.name;
          _this.delCursor.id = v.id;
          _this.type = "0"
          _this.delCursor.type = "1"
          _this.delCursor.index = i
          _this.delCursor.remarksName = v.name
          _this.delCursor.id = v.id
          // 将当前元素标红
          _this.ctx.strokeStyle = "red";
          _this.ctx.beginPath();
          _this.ctx.moveTo(v.location[0].x, v.location[0].y);
          _this.ctx.lineTo(v.location[1].x, v.location[1].y);
          _this.ctx.stroke();
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
          _this.c.style.cursor = "pointer";
          _this.ctx.strokeStyle = "red"
          _this.ctx.beginPath()
          _this.ctx.moveTo(v.location[0].x, v.location[0].y)
          _this.ctx.lineTo(v.location[1].x, v.location[1].y)
          _this.ctx.stroke()
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true)
          _this.c.style.cursor = "pointer"
        }
      });
      _this.canvasData.rect.forEach(function (v, i) {
        _this.ctx.strokeStyle = "yellow";
        _this.ctx.beginPath();
        _this.ctx.moveTo(v.location[0].x, v.location[0].y);
        _this.ctx.lineTo(v.location[1].x, v.location[1].y);
        _this.ctx.lineTo(v.location[2].x, v.location[2].y);
        _this.ctx.lineTo(v.location[3].x, v.location[3].y);
        _this.ctx.lineTo(v.location[0].x, v.location[0].y);
        _this.ctx.stroke();
        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
        _this.c.style.cursor = "pointer";
      })
      _this.canvasData.rect.forEach(function(v, i) {
        _this.ctx.strokeStyle = "yellow"
        _this.ctx.beginPath()
        _this.ctx.moveTo(v.location[0].x, v.location[0].y)
        _this.ctx.lineTo(v.location[1].x, v.location[1].y)
        _this.ctx.lineTo(v.location[2].x, v.location[2].y)
        _this.ctx.lineTo(v.location[3].x, v.location[3].y)
        _this.ctx.lineTo(v.location[0].x, v.location[0].y)
        _this.ctx.stroke()
        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false)
        _this.c.style.cursor = "pointer"
        if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
          // 如果传入了事件坐标,就用isPointInStroke判断一下
          // 当鼠标移入之后将当前的模式切换为选中模式
          _this.type = "0";
          _this.delCursor.type = "2";
          _this.delCursor.index = i;
          _this.delCursor.remarksName = v.name;
          _this.delCursor.id = v.id;
          _this.type = "0"
          _this.delCursor.type = "2"
          _this.delCursor.index = i
          _this.delCursor.remarksName = v.name
          _this.delCursor.id = v.id
          // console.log("当前选中元素:",_this.delCursor)
          // 将当前元素标红
          _this.ctx.strokeStyle = "red";
          _this.ctx.beginPath();
          _this.ctx.moveTo(v.location[0].x, v.location[0].y);
          _this.ctx.lineTo(v.location[1].x, v.location[1].y);
          _this.ctx.lineTo(v.location[2].x, v.location[2].y);
          _this.ctx.lineTo(v.location[3].x, v.location[3].y);
          _this.ctx.lineTo(v.location[0].x, v.location[0].y);
          _this.ctx.stroke();
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
          _this.selectedId = v.id;
          _this.c.style.cursor = "pointer";
          _this.ctx.strokeStyle = "red"
          _this.ctx.beginPath()
          _this.ctx.moveTo(v.location[0].x, v.location[0].y)
          _this.ctx.lineTo(v.location[1].x, v.location[1].y)
          _this.ctx.lineTo(v.location[2].x, v.location[2].y)
          _this.ctx.lineTo(v.location[3].x, v.location[3].y)
          _this.ctx.lineTo(v.location[0].x, v.location[0].y)
          _this.ctx.stroke()
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true)
          _this.selectedId = v.id
          _this.c.style.cursor = "pointer"
        }
      });
      _this.canvasData.arrow.forEach(function (v, i) {
        _this.ctx.strokeStyle = "yellow";
      })
      _this.canvasData.arrow.forEach(function(v, i) {
        _this.ctx.strokeStyle = "yellow"
        // _this.ctx.beginPath()
        // _this.ctx.moveTo(v.location[0].x, v.location[0].y)
        // _this.ctx.lineTo(v.location[1].x, v.location[1].y)
@@ -626,20 +562,20 @@
          ) * 0.1,
          2,
          "yellow"
        ); // 绘制方法
        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
        ) // 绘制方法
        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false)
        //_this.c.style.cursor = "pointer";
        if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
          // 如果传入了事件坐标,就用isPointInStroke判断一下  && _this.ctx.isPointInPath(e.offsetX, e.offsetY)
          // 如果当前环境覆盖了该坐标,就将图形的index放到数组里
          // 当鼠标移入之后将当前的模式切换为选中模式
          _this.type = "0";
          _this.delCursor.type = "4";
          _this.delCursor.index = i;
          _this.delCursor.remarksName = v.name;
          _this.delCursor.id = v.id;
          _this.type = "0"
          _this.delCursor.type = "4"
          _this.delCursor.index = i
          _this.delCursor.remarksName = v.name
          _this.delCursor.id = v.id
          // 将当前元素标红
          _this.ctx.strokeStyle = "red";
          _this.ctx.strokeStyle = "red"
          //   _this.ctx.beginPath()
          //   _this.ctx.moveTo(v.location[0].x, v.location[0].y)
          //   _this.ctx.lineTo(v.location[1].x, v.location[1].y)
@@ -657,46 +593,46 @@
            ) * 0.1,
            2,
            "red"
          ); // 绘制方法
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
          _this.c.style.cursor = "pointer";
          ) // 绘制方法
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true)
          _this.c.style.cursor = "pointer"
        }
      });
      _this.canvasData.polygon.forEach(function (v, i) {
      })
      _this.canvasData.polygon.forEach(function(v, i) {
        if (v.location.length !== 0) {
          _this.ctx.strokeStyle = "yellow";
          _this.ctx.beginPath();
          _this.ctx.moveTo(v.location[0].x, v.location[0].y);
          _this.ctx.strokeStyle = "yellow"
          _this.ctx.beginPath()
          _this.ctx.moveTo(v.location[0].x, v.location[0].y)
          for (let i = 1; i < v.location.length; i++) {
            _this.ctx.lineTo(v.location[i].x, v.location[i].y);
            _this.ctx.lineTo(v.location[i].x, v.location[i].y)
          }
          _this.ctx.closePath();
          _this.ctx.stroke();
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
          _this.c.style.cursor = "pointer";
          _this.ctx.closePath()
          _this.ctx.stroke()
          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false)
          _this.c.style.cursor = "pointer"
          if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
            // 如果传入了事件坐标,就用isPointInStroke判断一下
            // 如果当前环境覆盖了该坐标,就将图形的index放到数组里
            // 当鼠标移入之后将当前的模式切换为选中模式
            _this.type = "0";
            _this.delCursor.type = "5";
            _this.delCursor.index = i;
            _this.delCursor.remarksName = v.name;
            _this.delCursor.id = v.id;
            _this.type = "0"
            _this.delCursor.type = "5"
            _this.delCursor.index = i
            _this.delCursor.remarksName = v.name
            _this.delCursor.id = v.id
            // 将当前元素标红
            _this.ctx.strokeStyle = "red";
            _this.ctx.beginPath();
            _this.ctx.moveTo(v.location[0].x, v.location[0].y);
            _this.ctx.strokeStyle = "red"
            _this.ctx.beginPath()
            _this.ctx.moveTo(v.location[0].x, v.location[0].y)
            for (let i = 1; i < v.location.length; i++) {
              _this.ctx.lineTo(v.location[i].x, v.location[i].y);
              _this.ctx.lineTo(v.location[i].x, v.location[i].y)
            }
            _this.ctx.closePath();
            _this.ctx.stroke();
            _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
            _this.c.style.cursor = "pointer";
            _this.ctx.closePath()
            _this.ctx.stroke()
            _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true)
            _this.c.style.cursor = "pointer"
          }
        }
      });
      })
      // console.log("刚选中的图形:",_this.delCursor)
    },
    // 撤销
@@ -705,16 +641,16 @@
        // 正在画多边形,暂存数组里有坐标数据,可一步一步撤销
        if (this.points.length > 0) {
          if (this.points.length === 1) {
            this.type = "0"; // 不切换成‘0’把多边形撤销之后无法继续撤销其他图形
            this.flag = false;
            this.originX = null;
            this.originY = null;
            this.type = "0" // 不切换成‘0’把多边形撤销之后无法继续撤销其他图形
            this.flag = false
            this.originX = null
            this.originY = null
          }
          this.points.pop();
          this.ctx.clearRect(0, 0, this.c.width, this.c.height);
          this.loadImage();
          this.pointsUndo.splice(this.pointsUndo.length - 2, 1);
          this.drawPolygonUtil(this.pointsUndo);
          this.points.pop()
          this.ctx.clearRect(0, 0, this.c.width, this.c.height)
          this.loadImage()
          this.pointsUndo.splice(this.pointsUndo.length - 2, 1)
          this.drawPolygonUtil(this.pointsUndo)
        }
      } else {
        // 多边形已经完成或者是在画别的图形
@@ -727,159 +663,153 @@
                  this.canvasHistory[this.step].index,
                  this.canvasHistory[this.step].deleteLength,
                  this.canvasHistory[this.step].data
                );
                break;
                )
                break
              case "2":
                this.canvasData.rect.splice(
                  this.canvasHistory[this.step].index,
                  this.canvasHistory[this.step].deleteLength,
                  this.canvasHistory[this.step].data
                );
                break;
                )
                break
              case "4":
                this.canvasData.arrow.splice(
                  this.canvasHistory[this.step].index,
                  this.canvasHistory[this.step].deleteLength,
                  this.canvasHistory[this.step].data
                );
                break;
                )
                break
              case "5":
                this.canvasData.polygon.splice(
                  this.canvasHistory[this.step].index,
                  this.canvasHistory[this.step].deleteLength,
                  this.canvasHistory[this.step].data
                );
                break;
                )
                break
            }
            this.ctx.clearRect(0, 0, this.c.width, this.c.height);
            let canvasPic = new Image();
            canvasPic.src = this.canvasHistory[this.step - 1].src;
            let ctx = this.ctx;
            canvasPic.addEventListener("load", function () {
              ctx.drawImage(canvasPic, 0, 0);
            });
            this.step--;
            this.ctx.clearRect(0, 0, this.c.width, this.c.height)
            let canvasPic = new Image()
            canvasPic.src = this.canvasHistory[this.step - 1].src
            let ctx = this.ctx
            canvasPic.addEventListener("load", function() {
              ctx.drawImage(canvasPic, 0, 0)
            })
            this.step--
          } else if (this.canvasHistory[this.step].name !== undefined) {
            // 修改图形备注的撤销
            switch (this.canvasHistory[this.step].type) {
              case "1":
                this.canvasData.line[this.canvasHistory[this.step].index].name =
                  this.canvasHistory[this.step].name;
                break;
                this.canvasData.line[this.canvasHistory[this.step].index].name = this.canvasHistory[this.step].name
                break
              case "2":
                this.canvasData.rect[this.canvasHistory[this.step].index].name =
                  this.canvasHistory[this.step].name;
                break;
                this.canvasData.rect[this.canvasHistory[this.step].index].name = this.canvasHistory[this.step].name
                break
              case "4":
                this.canvasData.arrow[
                  this.canvasHistory[this.step].index
                ].name = this.canvasHistory[this.step].name;
                break;
                this.canvasData.arrow[this.canvasHistory[this.step].index].name = this.canvasHistory[this.step].name
                break
              case "5":
                this.canvasData.polygon[
                  this.canvasHistory[this.step].index
                ].name = this.canvasHistory[this.step].name;
                break;
                this.canvasData.polygon[this.canvasHistory[this.step].index].name = this.canvasHistory[this.step].name
                break
            }
            this.ctx.clearRect(0, 0, this.c.width, this.c.height);
            let canvasPic = new Image();
            canvasPic.src = this.canvasHistory[this.step - 1].src;
            let ctx = this.ctx;
            canvasPic.addEventListener("load", function () {
              ctx.drawImage(canvasPic, 0, 0);
            });
            this.step--;
            this.ctx.clearRect(0, 0, this.c.width, this.c.height)
            let canvasPic = new Image()
            canvasPic.src = this.canvasHistory[this.step - 1].src
            let ctx = this.ctx
            canvasPic.addEventListener("load", function() {
              ctx.drawImage(canvasPic, 0, 0)
            })
            this.step--
          } else {
            // 正常的撤销
            this.ctx.clearRect(0, 0, this.c.width, this.c.height);
            let canvasPic = new Image();
            this.ctx.clearRect(0, 0, this.c.width, this.c.height)
            let canvasPic = new Image()
            if (this.step > 0) {
              canvasPic.src = this.canvasHistory[this.step - 1].src;
              canvasPic.src = this.canvasHistory[this.step - 1].src
            }
            // 不知为何直接传进去this.ctx会是undefind,所以在外面转存一下
            let ctx = this.ctx;
            canvasPic.addEventListener("load", function () {
              ctx.drawImage(canvasPic, 0, 0);
            });
            let ctx = this.ctx
            canvasPic.addEventListener("load", function() {
              ctx.drawImage(canvasPic, 0, 0)
            })
            // 撤销最终数据
            switch (this.canvasHistory[this.step].type) {
              case "1":
                this.canvasData.line.pop();
                break;
                this.canvasData.line.pop()
                break
              case 2:
                this.canvasData.rect.pop();
                break;
                this.canvasData.rect.pop()
                break
              case 4:
                this.canvasData.arrow.pop();
                break;
                this.canvasData.arrow.pop()
                break
              case 5:
                this.canvasData.polygon.pop();
                this.points.length = 0;
                break;
                this.canvasData.polygon.pop()
                this.points.length = 0
                break
              case 0:
                // 将回显数据清空,相当于清空页面
                // console.log("撤销原始数据");
                this.clear();
                break;
                this.clear()
                break
            }
            this.step--;
            this.step--
          }
        } else {
          this.$notify({
            type: "warning",
            message: "不能再继续撤销了",
          });
            message: "不能再继续撤销了"
          })
        }
      }
      // console.log("撤销!",this.canvasData);
    },
    disabledOthers(type) {
      console.log("当前type:", type);
      console.log("当前type:", type)
      switch (type) {
        case "1":
          this.disableLine = false;
          this.disableRect = true;
          this.disableArrow = true;
          this.disablePolygon = true;
          this.disableSelect = true;
          break;
          this.disableLine = false
          this.disableRect = true
          this.disableArrow = true
          this.disablePolygon = true
          this.disableSelect = true
          break
        case "2":
          this.disableLine = true;
          this.disableRect = false;
          this.disableArrow = true;
          this.disablePolygon = true;
          this.disableSelect = true;
          break;
          this.disableLine = true
          this.disableRect = false
          this.disableArrow = true
          this.disablePolygon = true
          this.disableSelect = true
          break
        case "4":
          this.disableLine = true;
          this.disableRect = true;
          this.disableArrow = false;
          this.disablePolygon = true;
          this.disableSelect = true;
          break;
          this.disableLine = true
          this.disableRect = true
          this.disableArrow = false
          this.disablePolygon = true
          this.disableSelect = true
          break
        case "5":
          this.disableLine = true;
          this.disableRect = true;
          this.disableArrow = true;
          this.disablePolygon = false;
          this.disableSelect = true;
          break;
          this.disableLine = true
          this.disableRect = true
          this.disableArrow = true
          this.disablePolygon = false
          this.disableSelect = true
          break
      }
      console.log("禁用直线:", this.disableLine);
      console.log("禁用矩形:", this.disableRect);
      console.log("禁用箭头:", this.disableArrow);
      console.log("禁用多边形:", this.disablePolygon);
      console.log("禁用直线:", this.disableLine)
      console.log("禁用矩形:", this.disableRect)
      console.log("禁用箭头:", this.disableArrow)
      console.log("禁用多边形:", this.disablePolygon)
    },
    undisabled() {
      this.disableLine = false;
      this.disableRect = false;
      this.disableArrow = false;
      this.disablePolygon = false;
      this.disableSelect = false;
      this.disableLine = false
      this.disableRect = false
      this.disableArrow = false
      this.disablePolygon = false
      this.disableSelect = false
    },
    // 刷新底图
    refresh() {
      this.$emit("refresh");
      this.$emit("refresh")
      // this.$notify({
      //   type: 'success',
      //   message: '底图已刷新'
@@ -895,160 +825,155 @@
      // width:箭头线宽度
      // color:箭头颜色
      theta = typeof theta !== "undefined" ? theta : 30;
      headlen = typeof theta !== "undefined" ? headlen : 10;
      width = typeof width !== "undefined" ? width : 1;
      theta = typeof theta !== "undefined" ? theta : 30
      headlen = typeof theta !== "undefined" ? headlen : 10
      width = typeof width !== "undefined" ? width : 1
      // color = typeof color !== 'undefined' ? color : 'yellow'
      // 计算各角度和对应的P2,P3坐标
      let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
      let angle1 = ((angle + theta) * Math.PI) / 180;
      let angle2 = ((angle - theta) * Math.PI) / 180;
      let topX = headlen * Math.cos(angle1);
      let topY = headlen * Math.sin(angle1);
      let botX = headlen * Math.cos(angle2);
      let botY = headlen * Math.sin(angle2);
      let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI
      let angle1 = ((angle + theta) * Math.PI) / 180
      let angle2 = ((angle - theta) * Math.PI) / 180
      let topX = headlen * Math.cos(angle1)
      let topY = headlen * Math.sin(angle1)
      let botX = headlen * Math.cos(angle2)
      let botY = headlen * Math.sin(angle2)
      ctx.save();
      ctx.beginPath();
      let arrowX = fromX - topX;
      let arrowY = fromY - topY;
      ctx.moveTo(arrowX, arrowY);
      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.lineWidth = width;
      ctx.stroke();
      ctx.restore();
      ctx.save()
      ctx.beginPath()
      let arrowX = fromX - topX
      let arrowY = fromY - topY
      ctx.moveTo(arrowX, arrowY)
      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.lineWidth = width
      ctx.stroke()
      ctx.restore()
    },
    // 获取相对坐标(暂不用)
    getLocation(x, y, c) {
      let bbox = c.getBoundingClientRect();
      let bbox = c.getBoundingClientRect()
      return {
        x: (x - bbox.left) * (c.width / bbox.width),
        y: (y - bbox.top) * (c.height / bbox.height),
        y: (y - bbox.top) * (c.height / bbox.height)
        /*
          * 此处不用下面两行是为了防止使用CSS和JS改变了canvas的高宽之后是表面积拉大而实际
          * 显示像素不变而造成的坐标获取不准的情况
          x: (x - bbox.left),
          y: (y - bbox.top)
        */
      };
      }
    },
    // 生成图形备注
    remarks(x, y, type) {
      this.ctx.moveTo(x, y - 20);
      this.ctx.fillStyle = "green"; // 设置填充颜色为绿色
      this.ctx.font = '20px "微软雅黑"'; // 设置字体
      this.ctx.textBaseline = "bottom"; // 设置字体底线对齐绘制基线
      this.ctx.textAlign = "left"; // 设置字体对齐的方式
      let name = "";
      this.ctx.moveTo(x, y - 20)
      this.ctx.fillStyle = "green" // 设置填充颜色为绿色
      this.ctx.font = '20px "微软雅黑"' // 设置字体
      this.ctx.textBaseline = "bottom" // 设置字体底线对齐绘制基线
      this.ctx.textAlign = "left" // 设置字体对齐的方式
      let name = ""
      switch (type) {
        case "1":
          this.lineIndex++;
          name = "直线" + this.lineIndex;
          break;
          this.lineIndex++
          name = "直线" + this.lineIndex
          break
        case "2":
          this.rectIndex++;
          name = "矩形" + this.rectIndex;
          break;
          this.rectIndex++
          name = "矩形" + this.rectIndex
          break
        case "4":
          this.arrowIndex++;
          name = "箭头" + this.arrowIndex;
          break;
          this.arrowIndex++
          name = "箭头" + this.arrowIndex
          break
        case "5":
          this.polygonIndex++;
          name = "多边形" + this.polygonIndex;
          break;
          this.polygonIndex++
          name = "多边形" + this.polygonIndex
          break
      }
      this.ctx.fillText(name, x, y - 20); // 填充文字
      return name;
      this.ctx.fillText(name, x, y - 20) // 填充文字
      return name
    },
    // 回显图形备注
    showRemarks(x, y, remarks, isHightlight) {
      this.ctx.moveTo(x, y - 20);
      this.ctx.moveTo(x, y - 20)
      if (isHightlight) {
        this.ctx.fillStyle = "#8ae22e"; // 设置填充颜色为绿色
        this.ctx.fillStyle = "#8ae22e" // 设置填充颜色为绿色
      } else {
        this.ctx.fillStyle = "green"; // 设置填充颜色为绿色
        this.ctx.fillStyle = "green" // 设置填充颜色为绿色
      }
      this.ctx.font = '20px "微软雅黑"'; // 设置字体
      this.ctx.textBaseline = "bottom"; // 设置字体底线对齐绘制基线
      this.ctx.textAlign = "left"; // 设置字体对齐的方式
      this.ctx.fillText(remarks, x, y - 20); // 填充文字
      this.ctx.font = '20px "微软雅黑"' // 设置字体
      this.ctx.textBaseline = "bottom" // 设置字体底线对齐绘制基线
      this.ctx.textAlign = "left" // 设置字体对齐的方式
      this.ctx.fillText(remarks, x, y - 20) // 填充文字
    },
    // 重现保存画面
    loadImage() {
      if (this.step > -1) {
        let img = new Image();
        img.src = this.canvasHistory[this.step].src;
        this.ctx.drawImage(img, 0, 0, this.c.width, this.c.height);
        let img = new Image()
        img.src = this.canvasHistory[this.step].src
        this.ctx.drawImage(img, 0, 0, this.c.width, this.c.height)
      }
    },
    // 切换画线类型
    changeType(num) {
      if (num === "0") {
        this.c.style.cursor = "pointer";
        this.c.style.cursor = "pointer"
      } else {
        this.c.style.cursor = "crosshair";
        this.c.style.cursor = "crosshair"
      }
      this.type = num;
      this.type = num
    },
    // 绘制多边形方法
    drawPolygonUtil(points) {
      this.ctx.strokeStyle = "yellow";
      this.ctx.lineWidth = 2;
      this.ctx.beginPath();
      this.ctx.moveTo(points[0].x, points[0].y);
      this.ctx.strokeStyle = "yellow"
      this.ctx.lineWidth = 2
      this.ctx.beginPath()
      this.ctx.moveTo(points[0].x, points[0].y)
      for (let i = 1; i < points.length; i++) {
        this.ctx.lineTo(points[i].x, points[i].y);
        this.ctx.lineTo(points[i].x, points[i].y)
      }
      this.ctx.closePath();
      this.ctx.stroke();
      this.ctx.closePath()
      this.ctx.stroke()
    },
    // 画直线移动函数
    drawLine(e) {
      if (this.flag) {
        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
        this.loadImage();
        this.ctx.beginPath();
        this.ctx.strokeStyle = "yellow";
        this.c.style.cursor = "default";
        this.ctx.lineWidth = 2;
        this.ctx.moveTo(this.originX, this.originY);
        this.ctx.lineTo(e.offsetX, e.offsetY);
        this.ctx.stroke(); // 绘制
        this.ctx.clearRect(0, 0, this.c.width, this.c.height)
        this.loadImage()
        this.ctx.beginPath()
        this.ctx.strokeStyle = "yellow"
        this.c.style.cursor = "default"
        this.ctx.lineWidth = 2
        this.ctx.moveTo(this.originX, this.originY)
        this.ctx.lineTo(e.offsetX, e.offsetY)
        this.ctx.stroke() // 绘制
      }
    },
    // 画矩形移动函数
    drawRect(e) {
      if (this.flag) {
        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
        this.loadImage();
        this.ctx.beginPath();
        this.ctx.strokeStyle = "yellow";
        this.ctx.lineWidth = 2;
        this.ctx.strokeRect(
          this.originX,
          this.originY,
          e.offsetX - this.originX,
          e.offsetY - this.originY
        ); // 绘制方法
        this.ctx.clearRect(0, 0, this.c.width, this.c.height)
        this.loadImage()
        this.ctx.beginPath()
        this.ctx.strokeStyle = "yellow"
        this.ctx.lineWidth = 2
        this.ctx.strokeRect(this.originX, this.originY, e.offsetX - this.originX, e.offsetY - this.originY) // 绘制方法
      }
    },
    // 画箭头移动函数
    drawArrow(e) {
      if (this.flag) {
        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
        this.loadImage();
        this.ctx.lineWidth = 2;
        this.ctx.clearRect(0, 0, this.c.width, this.c.height)
        this.loadImage()
        this.ctx.lineWidth = 2
        this.drawArrowUtil(
          this.ctx,
          this.originX,
@@ -1056,339 +981,305 @@
          e.offsetX,
          e.offsetY,
          20,
          this.twoPointDistance(
            { x: this.originX, y: this.originY },
            { x: e.offsetX, y: e.offsetY }
          ) * 0.1,
          this.twoPointDistance({ x: this.originX, y: this.originY }, { x: e.offsetX, y: e.offsetY }) * 0.1,
          2,
          "yellow"
        ); // 绘制方法
        ) // 绘制方法
      }
    },
    twoPointDistance(p1, p2) {
      let dep = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
      return dep;
      let dep = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))
      return dep
    },
    // 画多边形移动函数
    drawPolygon(e) {
      if (this.flag) {
        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
        this.loadImage();
        this.ctx.clearRect(0, 0, this.c.width, this.c.height)
        this.loadImage()
        this.pointsUndo = this.points.concat({
          x: e.offsetX,
          y: e.offsetY,
        });
          y: e.offsetY
        })
        this.drawPolygonUtil(
          this.points.concat({
            // concat返回连接后的数组,原数组不变,相当于把移动的坐标作为一个虚假的坐标追加在后面,绝!
            x: e.offsetX,
            y: e.offsetY,
            y: e.offsetY
          })
        );
        )
      }
    },
    // 画直线抬起
    lineMouseUp(e) {
      if (
        Math.abs(this.originX - e.offsetX) < 5 &&
        Math.abs(this.originY - e.offsetY) < 5
      ) {
        this.flag = false;
        return;
      if (Math.abs(this.originX - e.offsetX) < 5 && Math.abs(this.originY - e.offsetY) < 5) {
        this.flag = false
        return
      }
      this.flag = false;
      let Id;
      let fileName;
      let coordinate = [];
      this.flag = false
      let Id
      let fileName
      let coordinate = []
      coordinate.push({
        x: this.originX,
        y: this.originY,
      });
        y: this.originY
      })
      coordinate.push({
        x: e.offsetX,
        y: e.offsetY,
      });
        y: e.offsetY
      })
      // console.log("line的editObj:",this.editObj)
      if (this.editObj.id == undefined) {
        Id = this.getUuid();
        fileName = this.remarks(this.originX, this.originY, "1");
        Id = this.getUuid()
        fileName = this.remarks(this.originX, this.originY, "1")
        this.canvasData.line.push({
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      } else {
        Id = this.editObj.id;
        fileName = this.editObj.remarksName;
        Id = this.editObj.id
        fileName = this.editObj.remarksName
        this.canvasData.line.splice(this.delCursor.index, 1, {
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      }
      this.clickSelect();
      this.undisabled();
      this.c.style.cursor = "crosshair";
      this.clickSelect()
      this.undisabled()
      this.c.style.cursor = "crosshair"
      // 将当前刚画完的图形加入删改游标,可以将刚画完的图形名称显示在左上角
      this.delCursor = {
        id: this.getUuid(),
        remarksName: fileName,
        type: "1",
        index: this.lineIndex - 1,
      };
      this.url = this.c.toDataURL(); // 每次 mouseup 都保存一次画布状态
      this.step++;
      this.canvasHistory.length = this.step; // 截断数组
      this.canvasHistory.push({ type: 1, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用
        index: this.lineIndex - 1
      }
      this.url = this.c.toDataURL() // 每次 mouseup 都保存一次画布状态
      this.step++
      this.canvasHistory.length = this.step // 截断数组
      this.canvasHistory.push({ type: 1, src: this.c.toDataURL("image/png") }) // 将快照保存到历史记录中以供撤销之用
      // this.changeType('0')
      this.freedEdit();
      this.freedEdit()
    },
    // 画矩形抬起
    rectMouseUp(e) {
      if (
        Math.abs(this.originX - e.offsetX) < 5 &&
        Math.abs(this.originY - e.offsetY) < 5
      ) {
        this.flag = false;
        return;
      if (Math.abs(this.originX - e.offsetX) < 5 && Math.abs(this.originY - e.offsetY) < 5) {
        this.flag = false
        return
      }
      this.flag = false;
      let coordinate = [];
      this.flag = false
      let coordinate = []
      // 逆时针算出矩形四角坐标
      coordinate.push({
        x: this.originX,
        y: this.originY,
      });
        y: this.originY
      })
      coordinate.push({
        x: this.originX,
        y: e.offsetY,
      });
        y: e.offsetY
      })
      coordinate.push({
        x: e.offsetX,
        y: e.offsetY,
      });
        y: e.offsetY
      })
      coordinate.push({
        x: e.offsetX,
        y: this.originY,
      });
      let Id;
      let fileName;
        y: this.originY
      })
      let Id
      let fileName
      // console.log("rect的editObj:",this.editObj)
      if (this.editObj.id == undefined) {
        Id = this.getUuid();
        fileName = this.remarks(this.originX, this.originY, "2");
        Id = this.getUuid()
        fileName = this.remarks(this.originX, this.originY, "2")
        this.canvasData.rect.push({
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      } else {
        Id = this.editObj.id;
        fileName = this.editObj.remarksName;
        Id = this.editObj.id
        fileName = this.editObj.remarksName
        this.canvasData.rect.splice(this.delCursor.index, 1, {
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      }
      this.clickSelect();
      this.undisabled();
      this.c.style.cursor = "crosshair";
      this.clickSelect()
      this.undisabled()
      this.c.style.cursor = "crosshair"
      this.delCursor = {
        id: Id,
        remarksName: fileName,
        type: "2",
        index: this.rectIndex - 1,
      };
        index: this.rectIndex - 1
      }
      // console.log("刚画完的矩形标志:",this.delCursor)
      this.url = this.c.toDataURL(); // 每次 mouseup 都保存一次画布状态
      this.step++;
      this.canvasHistory.length = this.step; // 截断数组
      this.canvasHistory.push({ type: 2, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用
      this.url = this.c.toDataURL() // 每次 mouseup 都保存一次画布状态
      this.step++
      this.canvasHistory.length = this.step // 截断数组
      this.canvasHistory.push({ type: 2, src: this.c.toDataURL("image/png") }) // 将快照保存到历史记录中以供撤销之用
      this.freedEdit();
      this.freedEdit()
    },
    // 画箭头时抬起
    arrowMouseUp(e) {
      if (
        Math.abs(this.originX - e.offsetX) < 5 &&
        Math.abs(this.originY - e.offsetY) < 5
      ) {
        this.flag = false;
        return;
      if (Math.abs(this.originX - e.offsetX) < 5 && Math.abs(this.originY - e.offsetY) < 5) {
        this.flag = false
        return
      }
      this.flag = false;
      let Id;
      let fileName;
      let coordinate = [];
      this.flag = false
      let Id
      let fileName
      let coordinate = []
      coordinate.push({
        x: this.originX,
        y: this.originY,
      });
        y: this.originY
      })
      coordinate.push({
        x: e.offsetX,
        y: e.offsetY,
      });
        y: e.offsetY
      })
      // console.log("arrow的editObj:",this.editObj)
      if (this.editObj.id == undefined) {
        Id = this.getUuid();
        fileName = this.remarks(this.originX, this.originY, "4");
        Id = this.getUuid()
        fileName = this.remarks(this.originX, this.originY, "4")
        this.canvasData.arrow.push({
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      } else {
        Id = this.editObj.id;
        fileName = this.editObj.remarksName;
        Id = this.editObj.id
        fileName = this.editObj.remarksName
        this.canvasData.arrow.splice(this.delCursor.index, 1, {
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      }
      this.clickSelect();
      this.undisabled();
      this.c.style.cursor = "crosshair";
      this.clickSelect()
      this.undisabled()
      this.c.style.cursor = "crosshair"
      // 将当前刚画完的图形加入删改游标,可以将刚画完的图形名称显示在左上角
      this.delCursor = {
        id: this.getUuid(),
        remarksName: fileName,
        type: "4",
        index: this.arrowIndex - 1,
      };
      this.url = this.c.toDataURL(); // 每次 mouseup 都保存一次画布状态
      this.step++;
      this.canvasHistory.length = this.step; // 截断数组
      this.canvasHistory.push({ type: 4, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用
        index: this.arrowIndex - 1
      }
      this.url = this.c.toDataURL() // 每次 mouseup 都保存一次画布状态
      this.step++
      this.canvasHistory.length = this.step // 截断数组
      this.canvasHistory.push({ type: 4, src: this.c.toDataURL("image/png") }) // 将快照保存到历史记录中以供撤销之用
      // this.changeType('0')
      this.freedEdit();
      this.freedEdit()
    },
    // 画多边形结束时双击
    polygonDblclick(e) {
      this.flag = false;
      this.points.pop(); // 双击之后多一个点的重复坐标,需要删除
      let Id;
      let fileName;
      let coordinate = [];
      this.flag = false
      this.points.pop() // 双击之后多一个点的重复坐标,需要删除
      let Id
      let fileName
      let coordinate = []
      this.points.map((item, index) => {
        coordinate.push(item);
      });
        coordinate.push(item)
      })
      // console.log("polygon的editObj:",this.editObj)
      if (this.editObj.id == undefined) {
        Id = this.getUuid();
        fileName = this.remarks(this.points[0].x, this.points[0].y, "5");
        Id = this.getUuid()
        fileName = this.remarks(this.points[0].x, this.points[0].y, "5")
        this.canvasData.polygon.push({
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      } else {
        Id = this.editObj.id;
        fileName = this.editObj.remarksName;
        Id = this.editObj.id
        fileName = this.editObj.remarksName
        this.canvasData.polygon.splice(this.delCursor.index, 1, {
          id: Id,
          name: fileName,
          location: coordinate,
        });
          location: coordinate
        })
      }
      this.clickSelect();
      this.undisabled();
      this.c.style.cursor = "crosshair";
      this.points.length = 0;
      this.clickSelect()
      this.undisabled()
      this.c.style.cursor = "crosshair"
      this.points.length = 0
      // 将当前刚画完的图形加入删改游标,可以将刚画完的图形名称显示在左上角
      this.delCursor = {
        id: this.getUuid(),
        remarksName: fileName,
        type: "5",
        index: this.polygonIndex - 1,
      };
      this.url = this.c.toDataURL();
      this.step++;
      this.canvasHistory.length = this.step; // 截断数组
      this.canvasHistory.push({ type: 5, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用
        index: this.polygonIndex - 1
      }
      this.url = this.c.toDataURL()
      this.step++
      this.canvasHistory.length = this.step // 截断数组
      this.canvasHistory.push({ type: 5, src: this.c.toDataURL("image/png") }) // 将快照保存到历史记录中以供撤销之用
      // this.changeType('0')
      // console.log("总数据:",this.canvasData)
      this.freedEdit();
      this.freedEdit()
    },
    // 释放编辑状态
    freedEdit() {
      this.editObj = {};
      this.editObj = {}
    },
    // 回显历史数据时计算一下回显的每种元素的数量以便生成图形注解时获得正确的开头
    indexInit() {
      this.lineIndex = this.canvasData.line.length;
      this.rectIndex = this.canvasData.rect.length;
      this.arrowIndex = this.canvasData.arrow.length;
      this.lineIndex = this.canvasData.line.length
      this.rectIndex = this.canvasData.rect.length
      this.arrowIndex = this.canvasData.arrow.length
      //排除this.canvasData.polygon全部区域(全部区域的id就是摄像机的id)
      let filterPolygonArr = this.canvasData.polygon.filter(
        (item) => item.id != this.TreeDataPool.selectedNode.id
      );
      this.polygonIndex = filterPolygonArr.length;
      let filterPolygonArr = this.canvasData.polygon.filter((item) => item.id != this.TreeDataPool.selectedNode.id)
      this.polygonIndex = filterPolygonArr.length
    },
    // 生成uuid
    getUuid() {
      let originStr = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
      let originChar = "0123456789abcdef";
      let len = originChar.length;
      return originStr.replace(/x/g, function (match) {
        return originChar.charAt(Math.floor(Math.random() * len));
      });
      let originStr = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
      let originChar = "0123456789abcdef"
      let len = originChar.length
      return originStr.replace(/x/g, function(match) {
        return originChar.charAt(Math.floor(Math.random() * len))
      })
    },
    // 判断一个点是否离一个图形的最小距离为n像素以内
    minDistance(x, y, locations, n) {
      let flag = false;
      let flag = false
      for (let i = 0; i < locations.length; i++) {
        if (i == locations.length - 1) {
          if (
            this.point2Line(
              x,
              y,
              locations[i].x,
              locations[i].y,
              locations[0].x,
              locations[0].y
            ) < n
          ) {
            flag = true;
          if (this.point2Line(x, y, locations[i].x, locations[i].y, locations[0].x, locations[0].y) < n) {
            flag = true
          }
        } else {
          if (
            this.point2Line(
              x,
              y,
              locations[i].x,
              locations[i].y,
              locations[i + 1].x,
              locations[i + 1].y
            ) < n
          ) {
            flag = true;
          if (this.point2Line(x, y, locations[i].x, locations[i].y, locations[i + 1].x, locations[i + 1].y) < n) {
            flag = true
          }
        }
      }
      return flag;
      return flag
    },
    point2Line(x, y, x1, y1, x2, y2) {
      let cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1); // |AB| * |AC|*cos(x)
      if (cross <= 0)
        return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1) + 0.0);
      let d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); // |AB|
      if (cross >= d2)
        return Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2) + 0.0);
      let cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1) // |AB| * |AC|*cos(x)
      if (cross <= 0) return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1) + 0.0)
      let d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) // |AB|
      if (cross >= d2) return Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2) + 0.0)
      let r = cross / d2;
      let px = x1 + (x2 - x1) * r; // C在 AB上的垂足点(px,py)
      let py = y1 + (y2 - y1) * r;
      return Math.sqrt((x - px) * (x - px) + (y - py) * (y - py) + 0.0); //两点间距离公式
    },
      let r = cross / d2
      let px = x1 + (x2 - x1) * r // C在 AB上的垂足点(px,py)
      let py = y1 + (y2 - y1) * r
      return Math.sqrt((x - px) * (x - px) + (y - py) * (y - py) + 0.0) //两点间距离公式
    }
  },
  props: {
    isGB28181: {
      default: false,
      type: Boolean,
      type: Boolean
    },
    // isShowDrawArrow: {
    //   default: false,
@@ -1396,7 +1287,7 @@
    // },
    disabled: {
      default: false,
      type: Boolean,
      type: Boolean
    },
    canvasDataToChild: {
      default: () => {
@@ -1404,17 +1295,17 @@
          line: [],
          rect: [],
          arrow: [],
          polygon: [],
        };
          polygon: []
        }
      },
      type: Object,
      type: Object
    },
    snapshot_url: {
      type: String,
      default: "",
    },
  },
};
      default: ""
    }
  }
}
</script>
<style lang="scss" scoped>
.header {