<template>
  <div class="drawPicBox">
    <h3>这里是绘制图片</h3>
    <div class="picCanvans">
      <div class="wrap">
        <img
          @load="onImageLoad"
          :src="
            'http://192.168.50.200:88/images/' +
            this.parentdata.name +
            '/' +
            currentNodeData.name
          "
          alt=""
          class="img"
          ref="imgDiv"
        />
        <canvas
          class="canvas_dom"
          id="canvasDom"
          :width="imgWidth"
          :height="imgHeight"
          @mousemove="moveFunction"
          @mousedown="downFunction"
          @mouseup="upFunction"
          @mouseout="outFunction"
          @contextmenu="contextMenuFunction"
        >
        </canvas>
      </div>
    </div>
  </div>
</template>
<script>
import EventBus from "@/utils/event-bus";
export default {
  components: {},
  data() {
    return {
      currentNodeData: "",
      parentdata: "",
      imgWidth: 0,
      imgHeight: 0,

      // 保存矩形数据
      recArrs: [],
      curObj: {
        isRightClick: false, // 鼠标右键按下标识
        radious: 4, // 范围误差值
        recSize: 5, // 移动小框的大小
        index: -1, // 当前矩形框的index
        side: 0, // 边界值
        resize: false, // 是否拖拽大小
        draw: false, // 是否画图
        drag: false, // 是否拖动
        x: 0, // 画图的起始x
        y: 0, // 画图的起始y
        startX: 0, // x轴开始位置
        startY: 0, // y轴开始位置
      },
      canvasWidth: this.imgWidth,
      canvasHeight: this.imgHeight,
    };
  },
  created() {
    EventBus.$on("currentNodeData", (value) => {
      //console.log(value); // 输出 value
      this.currentNodeData = value;
    });
    EventBus.$on("perentNode", (value) => {
      //console.log(value); // 输出 value
      this.parentdata = value;
    });
  },
  mounted() {},
  computed: {},
  methods: {
    //获取图片的宽高
    onImageLoad(event) {
      this.imgWidth = event.target.width;
      this.imgHeight = event.target.height;
    },
    // // 拖动图片
    // move(e) {
    //   e.preventDefault();
    //   // 获取元素
    //   var left = document.querySelector(".wrap");
    //   var img = document.querySelector(".img");
    //   var x = e.pageX - img.offsetLeft;
    //   var y = e.pageY - img.offsetTop;
    //   // 添加鼠标移动事件
    //   left.addEventListener("mousemove", move);
    //   function move(e) {
    //     img.style.left = e.pageX - x + "px";
    //     img.style.top = e.pageY - y + "px";
    //   }
    //   // 添加鼠标抬起事件，鼠标抬起，将事件移除
    //   img.addEventListener("mouseup", function () {
    //     left.removeEventListener("mousemove", move);
    //   });
    //   // 鼠标离开父级元素，把事件移除
    //   left.addEventListener("mouseout", function () {
    //     left.removeEventListener("mousemove", move);
    //   });
    // },
    // // 缩放图片
    // rollImg() {
    //   /* 获取当前页面的缩放比 若未设置zoom缩放比，则为默认100%，即1，原图大小 */
    //   var zoom = parseInt(this.$refs.imgDiv.style.zoom) || 100;
    //   /* event.wheelDelta 获取滚轮滚动值并将滚动值叠加给缩放比zoom wheelDelta统一为±120，其中正数表示为向上滚动，负数表示向下滚动 */
    //   zoom += event.wheelDelta / 12;
    //   /* 最小范围 和 最大范围 的图片缩放尺度 */
    //   if (zoom >= 100 && zoom < 400) {
    //     this.$refs.imgDiv.style.zoom = zoom + "%";
    //   }
    //   return false;
    // },
    // 禁止鼠标右键
    contextMenuFunction(e) {
      e.preventDefault();
      return false;
    },
    // 鼠标移出画布
    outFunction(e) {
      let canvasDom = document.getElementById("canvasDom");
      let x = e.clientX;
      let y = e.clientY;

      let left = canvasDom.offsetLeft;
      let top = canvasDom.offsetTop;
      let width = canvasDom.offsetWidth;
      let height = canvasDom.offsetHeight;

      let limitX = left + width;
      let limitY = top + height;

      if (x < left || x > limitX || y < top || y > limitY) {
        console.log("鼠标移出范围， 清除canvas，重新绘制");
        this.clearCanvas();
        this.drawOldRect();
      }
    },
    // 鼠标移动事件
    moveFunction(e) {
      // console.log('鼠标移动', e);
      // 需要清除之前的辅助线
      this.clearCanvas();
      // 画辅助线
      this.drawRuler(e);
      // 清空辅助线和矩形数据后，这里重绘
      this.drawOldRect();
      // 画矩形
      this.drawRect(e);
      // 移动或缩放
      this.moveOrScale(e);
    },
    // 移动矩形框/缩放矩形框
    moveOrScale(e) {
      let index = this.getEventIndex(e.offsetX, e.offsetY);
      let side = 0;
      if (index > -1) {
        side = this.getEventArea(index, e.offsetX, e.offsetY);
        // 画移动小框
        if (side > 0) {
          this.drawLitRecs(index);
        }
      }
      // 鼠标样式
      this.changeResizeCursor(side);

      // 如果在移动
      this.moveRec(e);

      // 如果在缩放
      this.reSizeRec(e);
    },
    // 移动
    moveRec(e) {
      if (this.curObj.drag && this.recArrs[this.curObj.index]) {
        let x = this.curObj.startX + e.offsetX - this.curObj.x;
        let y = this.curObj.startY + e.offsetY - this.curObj.y;

        let minX = canvasDom.offsetLeft;
        let maxX =
          canvasDom.offsetLeft +
          canvasDom.offsetWidth -
          this.recArrs[this.curObj.index].w;
        let minY = canvasDom.offsetTop;
        let maxY =
          canvasDom.offsetTop +
          canvasDom.offsetHeight -
          this.recArrs[this.curObj.index].h;

        if (x < minX) {
          x = minX;
        }
        if (x > maxX) {
          x = maxX;
        }
        if (y < minY) {
          y = minY;
        }
        if (y > maxY) {
          y = maxY;
        }

        this.recArrs[this.curObj.index].x = x;
        this.recArrs[this.curObj.index].y = y;
      }
    },
    // 缩放
    reSizeRec(e) {
      const { side, index, recSize } = this.curObj;
      const rec = this.recArrs[index];
      if (this.curObj.resize && rec) {
        const temX = rec.x;
        const temY = rec.y;
        const ex = e.offsetX;
        const ey = e.offsetY;
        if (side < 4 && temX + rec.w - ex > recSize) {
          rec.x = ex;
        }
        if (
          (side == 1 || side == 4 || side == 7) &&
          temY + rec.h - ey > recSize
        ) {
          rec.y = ey;
        }
        if (side < 4) {
          if (temX + rec.w - ex > recSize) {
            rec.w = temX + rec.w - ex;
          }
        } else if (side < 7) {
          if (ex - temX > recSize) {
            rec.w = ex - temX;
          }
        }
        if (side == 1 || side == 4 || side == 7) {
          if (temY + rec.h - ey > recSize) {
            rec.h = temY + rec.h - ey;
          }
        } else if (side == 3 || side == 6 || side == 8) {
          if (ey - temY > recSize) {
            rec.h = ey - temY;
          }
        }
      }
    },
    // 鼠标移动，画辅助线
    drawRuler(e) {
      let canvasDom = document.getElementById("canvasDom");
      let ctx2d = canvasDom.getContext("2d");
      // 开始一条路径
      ctx2d.beginPath();
      // 填充色
      ctx2d.fillStyle = "rgba(0,0,0,0.3)";
      ctx2d.strokeStyle = "red";

      // 路径宽度
      ctx2d.lineWidth = 1;
      // 移动到 鼠标的 x位置， y位置 0（竖线的起点）
      ctx2d.moveTo(e.offsetX, 0);
      // lineTo() 方法添加一个新点，（竖线的终点）
      ctx2d.lineTo(e.offsetX, this.canvasHeight);
      // 移动到(x: 0, y：鼠标的位置)（横线的起点）
      ctx2d.moveTo(0, e.offsetY);
      // lineTo() 方法添加一个新点，（横线的终点）
      ctx2d.lineTo(this.canvasWidth, e.offsetY);
      ctx2d.stroke();
    },
    // 清除canvas
    clearCanvas() {
      let ctx2d = canvasDom.getContext("2d");
      ctx2d.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
    },
    // 鼠标按下并移动，画矩形
    drawRect(e) {
      let ctx2d = canvasDom.getContext("2d");
      if (this.curObj.draw) {
        ctx2d.fillRect(
          this.curObj.x,
          this.curObj.y,
          e.offsetX - this.curObj.x,
          e.offsetY - this.curObj.y
        );
      }
    },
    // 画初始数据
    drawOldRect() {
      let ctx2d = canvasDom.getContext("2d");
      if (!this.recArrs.length) return;
      for (var i = 0; i < this.recArrs.length; i++) {
        // >2的判断是为了防止误触画出来的数据
        if (this.recArrs[i].w > 2 && this.recArrs[i].h > 2) {
          ctx2d.beginPath();
          ctx2d.lineWidth = 2; // 矩形框的线条宽度
          ctx2d.fillStyle = "rgba(0,0,0,0.3)";
          ctx2d.strokeStyle = "rgb(255, 0, 0)"; // 矩形框的线条颜色

          ctx2d.fillRect(
            this.recArrs[i].x,
            this.recArrs[i].y,
            this.recArrs[i].w,
            this.recArrs[i].h
          ); // 矩形框

          // 如果有文本信息，填充文本信息
          if (this.recArrs[i].text) {
            ctx2d.fillStyle = "purple";
            ctx2d.font = "14px 微软雅黑";
            ctx2d.lineWidth = 1;
            ctx2d.fillStyle = "rgba(0,0,0,0.3)";
            ctx2d.strokeStyle = "rgb(255,0,0)";

            ctx2d.strokeText(
              this.recArrs[i].text,
              this.recArrs[i].x +
                this.recArrs[i].w / 2 -
                (this.recArrs[i].text.length / 2) * 16,
              this.recArrs[i].y - 20 < 0
                ? this.recArrs[i].y + this.recArrs[i].h + 20
                : this.recArrs[i].y - 10
            );
          }
        }
      }
    },
    // 鼠标按下事件
    downFunction(e) {
      console.log("鼠标按下", e); // e.button 0 鼠标左键 1 鼠标滚轮 2 鼠标右键
      this.curObj.isRightClick = e.button > 1;
      console.log("是否右键", this.curObj.isRightClick);

      // 赋值 x,y 轴起始数据
      this.curObj.x = e.offsetX;
      this.curObj.y = e.offsetY;

      // 判断是否落在的矩形框上
      //得到落点所在框的序数
      this.curObj.index = this.getEventIndex(this.curObj.x, this.curObj.y);
      console.log("落点矩形", this.curObj.index);

      // 如果是鼠标右键 TODO...
      if (this.curObj.isRightClick) {
      } else {
        // 鼠标左键
        // 如果鼠标落点不在矩形内，画矩形
        if (this.curObj.index === -1) {
          this.curObj.draw = true;
        } else {
          // 落点在矩形内
          //移动或者放缩
          this.curObj.startX = this.recArrs[this.curObj.index].x;
          this.curObj.startY = this.recArrs[this.curObj.index].y;
          //得到落点在一个框中的区域
          this.curObj.side = this.getEventArea(
            this.curObj.index,
            this.curObj.x,
            this.curObj.y
          );
          console.log("this.curObj.side", this.curObj.side);
          if (this.curObj.side < 9) {
            //准备缩放
            console.log("在缩放");
            this.curObj.resize = true;
          } else {
            //准备拖动
            console.log("在拖动");
            this.curObj.drag = true;
          }

          // 画移动小框
          this.drawLitRecs(this.curObj.index);
        }
      }
      //判断小框类型
      this.changeResizeCursor(this.curObj.side);
    },
    // 修改鼠标样式
    changeResizeCursor(side) {
      let canvasDom = document.getElementById("canvasDom");
      switch (side) {
        case 0:
          canvasDom.style.cursor = "crosshair";
          break;
        case 1:
          canvasDom.style.cursor = "se-resize";
          break;
        case 2:
          canvasDom.style.cursor = "e-resize";
          break;
        case 3:
          canvasDom.style.cursor = "ne-resize";
          break;
        case 4:
          canvasDom.style.cursor = "sw-resize";
          break;
        case 5:
          canvasDom.style.cursor = "w-resize";
          break;
        case 6:
          canvasDom.style.cursor = "nw-resize";
          break;
        case 7:
          canvasDom.style.cursor = "s-resize";
          break;
        case 8:
          canvasDom.style.cursor = "n-resize";
          break;
        case 9:
          canvasDom.style.cursor = "move";
          break;
        default:
          canvasDom.style.cursor = "default";
      }
    },
    //得到落点在一个框中的区域
    getEventArea(index, x, y) {
      const { radious } = this.curObj;
      const data = this.recArrs[index];
      console.log("this.recArrs", this.recArrs);
      console.log("data", data);
      if (x > data.x - radious && x < data.x + radious) {
        if (y > data.y - radious && y < data.y + radious) {
          return 1;
        } else if (y > data.y + radious && y < data.y + data.h - radious) {
          return 2;
        } else if (
          y > data.y + data.h - radious &&
          y < data.y + data.h + radious
        ) {
          return 3;
        }
      } else if (
        x > data.x + data.w - radious &&
        x < data.x + data.w + radious
      ) {
        if (y > data.y - radious && y < data.y + radious) {
          return 4;
        } else if (y > data.y + radious && y < data.y + data.h - radious) {
          return 5;
        } else if (
          y > data.y + data.h - radious &&
          y < data.y + data.h + radious
        ) {
          return 6;
        }
      } else {
        if (
          y > data.y - radious &&
          y < data.y + radious &&
          x > data.x + radious &&
          x < data.x + data.w - radious
        ) {
          return 7;
        } else if (
          y > data.y + data.h - radious &&
          y < data.y + data.h + radious &&
          x > data.x + radious &&
          x < data.x + data.w - radious
        ) {
          return 8;
        } else {
          return 9;
        }
      }
    },
    //把一个框的左上角坐标和宽高输入，得到8个坐标，左3，右3中2
    prepareLitRecs(index) {
      const data = this.recArrs[index];
      var li = [];
      li[0] = [data.x, data.y];
      li[1] = [data.x, data.y + data.h / 2];
      li[2] = [data.x, data.y + data.h];
      li[3] = [data.x + data.w, data.y];
      li[4] = [data.x + data.w, data.y + data.h / 2];
      li[5] = [data.x + data.w, data.y + data.h];
      li[6] = [data.x + data.w / 2, data.y];
      li[7] = [data.x + data.w / 2, data.y + data.h];
      return li;
    },
    //画移动时的小框,data为矩形框9个点的坐标
    drawLitRecs(index) {
      let ctx2d = canvasDom.getContext("2d");
      const data = this.prepareLitRecs(index);
      const { recSize } = this.curObj;
      for (var i = 0; i < data.length; i++) {
        ctx2d.fillRect(
          data[i][0] - recSize / 2,
          data[i][1] - recSize / 2,
          recSize,
          recSize
        );
      }
    },
    // 获取鼠标落点所在矩形的index, -1 表示没有落在任何框内
    getEventIndex(x, y) {
      if (!this.recArrs.length) return -1;
      for (var i = 0; i < this.recArrs.length; i++) {
        const limitX = x > this.recArrs[i].x - this.curObj.radious;
        const limitW =
          x < this.recArrs[i].x + this.recArrs[i].w + this.curObj.radious;
        const limitY = y > this.recArrs[i].y - this.curObj.radious;
        const limitH =
          y < this.recArrs[i].y + this.recArrs[i].h + this.curObj.radious;
        // 有在范围内的，返回index
        if (limitX && limitY && limitW && limitH) {
          return i;
        }
        // 没有返回 -1
        if (i == this.recArrs.length - 1) {
          return -1;
        }
      }
    },
    // 鼠标抬起事件
    upFunction(e) {
      console.log("鼠标抬起", e);
      if (this.curObj.isRightClick) {
        if (this.curObj.index !== -1) {
          // 删除，重绘
          this.recArrs.splice(this.curObj.index, 1);
          this.clearCanvas();
          this.drawOldRect();
        }
        this.curObj.isRightClick = false;
        return;
      }

      this.curObj.resize = false;
      this.curObj.drag = false;

      // 如果是画图
      if (this.curObj.draw) {
        this.addToRecs(e);
        this.curObj.draw = false;
      }

      console.log("鼠标抬起-当前矩形框", this.recArrs);
    },
    // 添加矩形
    addToRecs(e) {
      let rec = {
        x: this.curObj.x > e.offsetX ? e.offsetX : this.curObj.x, // x点
        y: this.curObj.y > e.offsetY ? e.offsetY : this.curObj.y, // y点
        w: Math.abs(e.offsetX - this.curObj.x), // 宽
        h: Math.abs(e.offsetY - this.curObj.y), // 高
        text: "矩形框" + this.recArrs.length, // 默认填充文本
        type: 1, // 类型
        // 其他需要的数据自行添加...
      };
      // 防止误触
      if (rec.w > 2 && rec.h > 2) {
        this.recArrs.push(rec);
        console.log("recArrs", this.recArrs);
      }
    },
  },
};
</script>
<style lang="less">
.drawPicBox {
  width: 100%;
  height: 100%;
  h3 {
    margin-bottom: 16px;
  }
  .picCanvans {
    width: 100%;
    height: calc(100% - 42px);
    overflow: hidden;
    .wrap {
      width: 100%;
      height: 100%;
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;
      overflow: hidden;
      border: 1px solid #dcdfe6;
      background: rgba(0, 0, 0, 0.3);
      img {
        position: absolute;
        max-width: auto;
        max-height: 800px;
        cursor: move;
      }
      .canvas_dom {
        //background-color: rgba(255, 0, 0, 0.2);
        cursor: crosshair;
        position: absolute;
      }
    }
  }
}
</style>
