图片四角可控制,实现图片拉伸,缩放,拖动位置

效果如图

代码如下:

<template>
  <div>
    <div
      ref="dragRef"
      :class="['es-drager', { dragerbor: selected }]"
      :style="dragStyle"
      @mousedown="onMousedown"
    >
      <img src="../../assets//images/qianming.svg" :style="dragStyle" />     

      <div v-show="selected">
        <div
          v-for="item in dotList"
          :key="item.side"
          class="es-drager-dot"
          :data-side="item.side"
          :style="getDotStyle(item)"
          @mousedown="onDotMousedown(item, $event)"
        ></div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "MyprojectScale",

  data() {
    return {
      selected: true,
      isMousedown:false,
      dotList: [
        { side: "top", cursor: "n-resize" },
        { side: "bottom", cursor: "n-resize" },
        { side: "left", cursor: "e-resize" },
        { side: "right", cursor: "e-resize" },
        { side: "top-left", cursor: "se-resize" },
        { side: "top-right", cursor: "sw-resize" },
        { side: "bottom-left", cursor: "sw-resize" },
        { side: "bottom-right", cursor: "se-resize" },
      ],
      dragData: {
        width: 100,
        height: 100,
        left: 0,
        top: 0,
      },
    };
  },

  mounted() {},
  computed: {
    dragStyle: function () {
      const { width, height, left, top } = this.dragData;
      return {
        width: parseInt(width) + "px",
        height: parseInt(height) + "px",
        left: parseInt(left) + "px",
        top: parseInt(top) + "px",
        //"--es-drager-color": props.color,
      };
    },
  },
  methods: {
    onMousedown(e) {
      this.isMousedown= true;
      const el = this.$refs.dragRef;

      // 记录按下的位置
      const downX = e.clientX;
      const downY = e.clientY;

      const elRect = el.getBoundingClientRect();
      // 鼠标在盒子里的位置
      const mouseX = downX - elRect.left;
      const mouseY = downY - elRect.top;

      const onMousemove = (e) => {
        // 当前鼠标的位置减去鼠标在盒子里的位置就是要移动的距离
        let moveX = e.clientX - mouseX;
        let moveY = e.clientY - mouseY;

        this.dragData.left = moveX;
        this.dragData.top = moveY;
        //emit && emit("move", dragData.value);
      };

      const onMouseup = (_e) => {
        this.isMousedown= false;
        // 移除document事件
        document.removeEventListener("mousemove", onMousemove);
        document.removeEventListener("mouseup", onMouseup);
      };
      // 位document注册鼠标移动事件
      document.addEventListener("mousemove", onMousemove);
      // 鼠标抬起事件
      document.addEventListener("mouseup", onMouseup);
    },
    getDotStyle(item) {
      const [side, position] = item.side.split("-");
      const style = { [side]: "0%", cursor: item.cursor };
      if (!position) {
        const side2 = ["top", "bottom"].includes(side) ? "left" : "top";
        style[side2] = "50%";
      } else {
        style[position] = "0%";
      }

      return style;
    },

    onDotMousedown(dotInfo, e) {
      e.stopPropagation();
      e.preventDefault();

      // 获取鼠标按下的坐标
      const downX = e.clientX;
      const downY = e.clientY;
      const el = this.$refs.dragRef;
      const elRect = el.getBoundingClientRect();
      console.log("elRect", elRect);

      const onMousemove = (e) => {
        // 移动的x距离
        const disX = e.clientX - downX;
        // 移动的y距离
        const disY = e.clientY - downY;

        const [side, position] = dotInfo.side.split("-");

       

        // 是否是上方缩放圆点
        const hasT = side === "top";
        // 是否是左方缩放圆点
        const hasL = [side, position].includes("left");

        let width = elRect.width + (hasL ? -disX : disX);
        let height = elRect.height + (hasT ? -disY : disY);

        // 如果是左侧缩放圆点,修改left位置
        let left = elRect.left + (hasL ? disX : 0);

        // 如果是上方缩放圆点,修改top位置
        let top = elRect.top + (hasT ? disY : 0);

        if (!position) {
          // 如果是四个正方位
          if (["top", "bottom"].includes(side)) {
            // 上下就不改变宽度
            width = elRect.width;
          } else {
            // 左右就不改变高度
            height = elRect.height;
          }
        }

        // 处理逆向缩放
        if (width < 0) {
          width = -width;
          left -= width;
        }
        if (height < 0) {
          height = -height;
          top -= height;
        }

        this.dragData = { left, top, width, height };
      };

      const onMouseup = (_e) => {
        document.removeEventListener("mousemove", onMousemove);
        document.removeEventListener("mouseup", onMouseup);
      };
      document.addEventListener("mousemove", onMousemove);
      document.addEventListener("mouseup", onMouseup);
    },
  },
};
</script>

<style lang="scss" scoped>
.es-drager {
  position: absolute;
  z-index: 1000;
}
.dragerbor {
  border: 1px solid #3a7afe;
}
.es-drager-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  //border-radius: 50%;
  background-color: #3a7afe;
  transform: translate(-50%, -50%);
  cursor: se-resize;
  &[data-side*="right"] {
    transform: translate(50%, -50%);
  }
  &[data-side*="bottom"] {
    transform: translate(-50%, 50%);
  }
  &[data-side="bottom-right"] {
    transform: translate(50%, 50%);
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值