vue开发可拖拽可放大模块的功能

开发中发现遇到一个小问题,只开发子组件时,拖拽移动位置正常,但实际到父组件中引入,鼠标按下之后并不能直接拖拽,而是鼠标抬起后拖拽内容跟随鼠标移动,再次鼠标按下抬起才能停止。

最后发现是由于L1Map组件内 img 标签原本就可以拖拽,导致出现此问题,在img标签配置

:draggable=“false” 既可解决。

可拖拽放大的组件代码

<template>
  <div
    class="resizable-draggable"
    :style="{ transform: `scale(${scale})`, left: `${x}px`, top: `${y}px` }"
    @mousedown="startDrag"
  >
    <slot></slot>
  </div>
</template>  

<script>
export default {
  name: 'ResizableDraggable',
  data() {
    return {
      dragging: false,
      resizing: false,
      startX: 0,
      startY: 0,
      scale: 1,
      x: 0,
      y: 0
    };
  },
  methods: {
    startDrag(event) {
      this.dragging = true;
      this.startX = event.clientX - this.x;
      this.startY = event.clientY - this.y;
      document.addEventListener('mousemove', this.drag);
      document.addEventListener('mouseup', this.stopDrag);
    },
    drag(event) {
      if (!this.dragging) return;
      this.x = event.clientX - this.startX;
      this.y = event.clientY - this.startY;
    },
    stopDrag() {
      if (!this.dragging) return;
      this.dragging = false;
      document.removeEventListener('mousemove', this.drag);
      document.removeEventListener('mouseup', this.stopDrag);
    },
    startResize(type) {
      this.resizing = true;
      const num = type === 'narrow' ? -0.2 : 0.2;
      this.scale += num;
      this.scale = Math.max(1, Math.min(this.scale, 2)); // 限制缩放范围
    },
    reset() {
      this.dragging = false;
      this.resizing = false;
      this.startX = 0;
      this.startY = 0;
      this.scale = 1;
      this.x = 0;
      this.y = 0;
    }
    // startResize(event) {
    //   this.resizing = true;
    //   const rect = this.$el.getBoundingClientRect();
    //   const scaleFactor = event.clientX - rect.left > rect.width / 2 ? 1.1 : 0.9;
    //   this.scale *= scaleFactor;
    //   this.scale = Math.max(0.1, Math.min(this.scale, 2)); // 限制缩放范围
    //   event.preventDefault();
    // }
  }
};
</script>  
  
<style scoped>
.resizable-draggable {
  width: 100%;
  height: 100%;
  position: absolute;
  transition: transform 0.2s ease-in-out;
  cursor: move;
  border: 1px solid #000;
  /* 其他样式 */
}

.resizer {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 10px;
  height: 10px;
  background: red;
  cursor: se-resize;
  /* 其他样式 */
}
</style>

父组件引用

<template>
  <div class="terminal-area">
    <div class="terminal-area-content">
      <div class="terminal-area-content-map">
        <div class="area-map">
          <MapBox ref="mapBox">
            <L1Map />
          </MapBox>
          <div class="resize-btns">
            <div class="resize-icon resize-large" @click.stop="handleResize('large')">
              <span class="el-icon-plus"></span>
            </div>
            <div class="resize-icon resize-narrow" @click.stop="handleResize('narrow')">
              <span class="el-icon-minus"></span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import MapBox from './components/MapBox';
import L1Map from './components/L1Map';
export default {
  components: { MapBox, L1Map },
  data() {
    return {
    };
  },
  methods: {
    handleResize(type) {
      this.$refs.mapBox.startResize(type);
    }
  }
};
</script>

<style lang="scss" scoped>
.terminal-area {
      .area-map {
        width: 100%;
        height: 0;
        flex: 1;
        background-image: url('~@/assets/terminalArea/mapBg.png');
        background-repeat: no-repeat;
        background-size: 100% 100%;
        position: relative;
        overflow: hidden;
        .resize-btns {
          width: 40px;
          height: 72px;
          background: #22335e;
          border-radius: 4px;
          position: absolute;
          bottom: 46px;
          right: 32px;
          z-index: 10;
          color: #fff;
          .resize-icon {
            width: 100%;
            height: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
          }
          .resize-narrow {
            border-top: 1px solid rgba(217, 217, 217, 0.12);
          }
        }
      }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值