本文介绍: dragenter元素拖进可drop元素绑定drop事件元素)时触发,作用于目标元素dragover:当元素拖动drop元素上时触发,作用于目标元素。dragleave :当元素离开drop元素时触发,作用于目标元素。drop:当元素放下到drop元素触发,作用于目标元素。1.父元素的宽-自适应ini父元素的高-自适应值。dragstart:开始拖元素触发,作用于拖拽元素。dragend:放开拖动元素时触发,作用于目标元素。drag:每次元素被拖动时会触发,作用于目标元素。
完成一次拖放事件过程是: dragstart –> dragenter –> dragover –> drop –> dragend
下面是HTML5的拖拽事件
dragstart:开始拖元素触发,作用于拖拽元素
dragenter:元素拖进可drop元素(绑定drop事件的元素)时触发,作用于目标元素
dragover:当元素拖动到drop元素上时触发,作用于目标元素
drop:当元素放下到drop元素触发,作用于目标元素
dragleave :当元素离开drop元素时触发,作用于目标元素
drag:每次元素被拖动时会触发,作用于目标元素
dragend:放开拖动元素时触发,作用于目标元素

 js获取鼠标滚动量/滚动了多少可以onwheel事件实现放大缩小。

html代码如下

<template>
    <div class="back_box" @click.stop="hide"
         v-if="isVisible" ref="back_box"
         :style="{background: isMaskVisible? 'rgba(0,0,0,0.5)' : 'none'}">
      <div
        class="drag_box"
        draggable="true"
        @dragstart="dragstart"
        @dragover="dragover"
        @dragend="dragend"
        @wheel="handleWeel"
        :style="`left:${elLeft}px;top:${elTop}px;width:${elWidth}px;height:${elHeight}px;`"
        @click.stop="show"
      >
        <div class="sotp" @click.stop="hide"><a-icon type="close" style="font-size: 20px;"/></div>
        <div
          class="content"
          :style="`left:${(0 * elWidth) / xWidth}px;top:${(0 * elHeight) / yHeight}px;width:${xWidth}px;height:${yHeight-50}px;-webkit-transform: scale(${meter_zoom} )`"
        >
          <div class="title" v-if="title">{{title}}</div>
          <slot name="content"></slot>
        </div>
      </div>
    </div>
</template>

  css代码主要用到positon:fixed让无素在窗口最上面

<style scoped lang="scss">
  .back_box {
    position: fixed;
    z-index: 9999;
    cursor: move;
  }

  .drag_box {
    position: fixed;
    overflow: hidden;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
    user-select: none; /* 不可选中,为了拖拽时不让文字高亮 */
    -webkit-user-drag: none;
  }

  .content {
    position: absolute;
    z-index: 88;
    width: 100%;
    padding: 0;
    overflow: hidden;
    font-size: 12px;
    transform-origin: 0 0; /* 用作缩放基点 */
    .title {
      height: 40px;
      padding: 10px;
      font-weight: 600;
      font-size: 14px;
      border-bottom: 1px solid #f5f5f5;
    }
  }

  .sotp {
    position: absolute;
    top: 10px;
    right: 20px;
    z-index: 999;
    width: 30px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    background: #fff;
    border-radius: 50%;
    cursor: pointer;
  }
</style>

 1.父元素的宽-自适应ini父元素的高-自适应值

2.元素拖拽距离浏览器的X轴位置

3.元素拖拽距离浏览器的Y轴位置

4.获取计算偏移量

5.获取元素的左偏移量

6.获取元素的右偏移量

7.设置缩放比例

8.元素宽 元素高

9.子元素缩放比例

<script>
  export default {
    name: 'HelloWorld',
    props: {
      msg: String,
      xWidth: {
        type: Number,
        default: 400
      },
      yHeight: {
        type: Number,
        default: 400
      },
      xLeft: { // 左侧偏移
        type: Number,
        default: 20
      },
      yTop: { // top偏移
        type: Number,
        default: 20
      },
      title: {
        type: String,
        default: ''
      },
      visible: {
        type: Boolean,
        default: false
      },
      maskVisible: {
        type: Boolean,
        default: false
      }
    },
    data () {
      return {
        initWidth: 0, // 父元素的宽-自适应值
        initHeight: 0, // 父元素的高-自适应值
        startclientX: 0, // 元素拖拽距离浏览器的X轴位置
        startclientY: 0, // 元素拖拽前距离浏览器的Y轴位置
        endlientX: 0, // 计算偏移量
        endlientY: 0,
        elLeft: 0, // 元素的左偏移量
        elTop: 0, // 元素的右偏移量
        zoom: 1, // 缩放比例
        elWidth: 0, // 元素宽
        elHeight: 0, // 元素高
        meter_zoom: 0, // 子元素缩放比例

        isVisible: false,
        isMaskVisible: false
      }
    },
    watch: {
      visible: {
        deep: true,
        handler (val) {
          if (val) {
            setTimeout(() => {
              this.initBodySize() // 页面初始化
            }, 50)
          }
          this.isVisible = val
        }
      },
      maskVisible: {
        deep: true,
        handler (val) {
          this.isMaskVisible = val
        }
      }
    },
    methods: {
      // 页面初始化
      initBodySize () {
        // this.initWidth = this.$refs.back_box.clientWidth // 拿到父元素宽
        // this.initHeight = this.initWidth * (1080 / 1920);
        this.initWidth = window.innerWidth
        this.initHeight = this.initWidth * ((1080 * 0.88) / (1920 - 1080 * 0.02)) // 根据宽计算实现自适应
        this.elWidth = this.initWidth * (this.xWidth / (1920 / 2))
        this.elHeight = this.initHeight * (this.yHeight / (1080 / 2))
        this.meter_zoom = this.elWidth / this.xWidth // 计算子元素缩放比例
        this.elLeft = this.elLeft
        this.elTop = this.elTop
      },
      // 拖拽开始事件
      dragstart (e) {
        this.startclientX = e.layerX // 记录拖拽元素初始位置
        this.startclientY = e.layerY
      },
      dragover (e) {
        let x = e.layerX - this.startclientX // 计算偏移量
        let y = e.layerY - this.startclientY
        this.elLeft += x // 实现拖拽元素随偏移移动
        this.elTop += y
      },
      // 拖拽完成事件
      dragend (e) {
        let x = e.layerX - this.startclientX // 计算偏移量
        let y = e.layerY - this.startclientY
        this.elLeft += x // 实现拖拽元素随偏移量移动
        this.elTop += y
      },
      // 滚轮放大缩小事件
      handleWeel (e) {
        if (e.wheelDelta < 0) {
          this.zoom -= 0.05
        } else {
          this.zoom += 0.05
        }
        if (this.zoom >= 3) {
          this.zoom = 3
          return
        }
        if (this.zoom <= 0.5) {
          this.zoom = 0.5
          return
        }
        this.elWidth = this.initWidth * (this.xWidth / (1920 / 2)) * this.zoom
        this.elHeight = this.initHeight * (this.yHeight / (1080 / 2)) * this.zoom
        this.meter_zoom = this.elWidth / this.xWidth
      },
      show () { // 显示
        this.isVisible = true
        this.initBodySize()
      },
      hide () { // 隐藏
        this.isVisible = false
        this.$emit('close')
      }
    },
    mounted () {
      // 监听键盘Esc按键事件
      this.$nextTick(() => {
        // 按下键盘
        document.addEventListener('keydown', (e) => {
          // Esc按键是27
          if (e.keyCode === 27) {
            // 在这里写你的操作逻辑
            this.hide()
          }
        })

        // 去除默认预览图
        // 虽然setDragImage比较鸡肋,但是我们可以设置一张透明图片可以实现去除默认预览图的效果document.addEventListener('dragstart', function (ev) {
          let img = new Image()
          img.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E"
          ev.dataTransfer.setDragImage(img, 0, 0)
        })
      })
    }

  }
</script>

监听键盘Esc按键事件关闭弹框

  // 监听键盘Esc按键事件
      this.$nextTick(() => {
        // 按下键盘
        document.addEventListener('keydown', (e) => {
          // Esc按键是27
          if (e.keyCode === 27) {
            // 在这里写你的操作逻辑
            this.hide()
          }
        })

 需注意:去除默认预览

虽然setDragImage比较鸡肋,但是我们可以设置一张透明的图片就可以实现去除默认预览图的效果
      document.addEventListener('dragstart', function (ev) {
          let img = new Image()
          img.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E"
          ev.dataTransfer.setDragImage(img, 0, 0)
        })
      })

全部源代码

<template>
    <div class="back_box" @click.stop="hide"
         v-if="isVisible" ref="back_box"
         :style="{background: isMaskVisible? 'rgba(0,0,0,0.5)' : 'none'}">
      <div
        class="drag_box"
        draggable="true"
        @dragstart="dragstart"
        @dragover="dragover"
        @dragend="dragend"
        @wheel="handleWeel"
        :style="`left:${elLeft}px;top:${elTop}px;width:${elWidth}px;height:${elHeight}px;`"
        @click.stop="show"
      >
        <div class="sotp" @click.stop="hide"><a-icon type="close" style="font-size: 20px;"/></div>
        <div
          class="content"
          :style="`left:${(0 * elWidth) / xWidth}px;top:${(0 * elHeight) / yHeight}px;width:${xWidth}px;height:${yHeight-50}px;-webkit-transform: scale(${meter_zoom} )`"
        >
          <div class="title" v-if="title">{{title}}</div>
          <slot name="content"></slot>
        </div>
      </div>
    </div>
</template>

<script>
  export default {
    name: 'HelloWorld',
    props: {
      msg: String,
      xWidth: {
        type: Number,
        default: 400
      },
      yHeight: {
        type: Number,
        default: 400
      },
      xLeft: { // 左侧偏移
        type: Number,
        default: 20
      },
      yTop: { // top偏移
        type: Number,
        default: 20
      },
      title: {
        type: String,
        default: ''
      },
      visible: {
        type: Boolean,
        default: false
      },
      maskVisible: {
        type: Boolean,
        default: false
      }
    },
    data () {
      return {
        initWidth: 0, // 父元素的宽-自适应值
        initHeight: 0, // 父元素的高-自适应值
        startclientX: 0, // 元素拖拽前距离浏览器的X轴位置
        startclientY: 0, // 元素拖拽前距离浏览器的Y轴位置
        endlientX: 0, // 计算偏移量
        endlientY: 0,
        elLeft: 0, // 元素的左偏移量
        elTop: 0, // 元素的右偏移量
        zoom: 1, // 缩放比例
        elWidth: 0, // 元素宽
        elHeight: 0, // 元素高
        meter_zoom: 0, // 子元素缩放比例

        isVisible: false,
        isMaskVisible: false
      }
    },
    watch: {
      visible: {
        deep: true,
        handler (val) {
          if (val) {
            setTimeout(() => {
              this.initBodySize() // 页面初始化
            }, 50)
          }
          this.isVisible = val
        }
      },
      maskVisible: {
        deep: true,
        handler (val) {
          this.isMaskVisible = val
        }
      }
    },
    methods: {
      // 页面初始化
      initBodySize () {
        // this.initWidth = this.$refs.back_box.clientWidth // 拿到父元素宽
        // this.initHeight = this.initWidth * (1080 / 1920);
        this.initWidth = window.innerWidth
        this.initHeight = this.initWidth * ((1080 * 0.88) / (1920 - 1080 * 0.02)) // 根据宽计算高实现自适应
        this.elWidth = this.initWidth * (this.xWidth / (1920 / 2))
        this.elHeight = this.initHeight * (this.yHeight / (1080 / 2))
        this.meter_zoom = this.elWidth / this.xWidth // 计算子元素缩放比例
        this.elLeft = this.elLeft
        this.elTop = this.elTop
      },
      // 拖拽开始事件
      dragstart (e) {
        this.startclientX = e.layerX // 记录拖拽元素初始位置
        this.startclientY = e.layerY
      },
      dragover (e) {
        let x = e.layerX - this.startclientX // 计算偏移量
        let y = e.layerY - this.startclientY
        this.elLeft += x // 实现拖拽元素随偏移量移动
        this.elTop += y
      },
      // 拖拽完成事件
      dragend (e) {
        let x = e.layerX - this.startclientX // 计算偏移量
        let y = e.layerY - this.startclientY
        this.elLeft += x // 实现拖拽元素随偏移量移动
        this.elTop += y
      },
      // 滚轮放大缩小事件
      handleWeel (e) {
        if (e.wheelDelta < 0) {
          this.zoom -= 0.05
        } else {
          this.zoom += 0.05
        }
        if (this.zoom >= 3) {
          this.zoom = 3
          return
        }
        if (this.zoom <= 0.5) {
          this.zoom = 0.5
          return
        }
        this.elWidth = this.initWidth * (this.xWidth / (1920 / 2)) * this.zoom
        this.elHeight = this.initHeight * (this.yHeight / (1080 / 2)) * this.zoom
        this.meter_zoom = this.elWidth / this.xWidth
      },
      show () { // 显示
        this.isVisible = true
        this.initBodySize()
      },
      hide () { // 隐藏
        this.isVisible = false
        this.$emit('close')
      }
    },
    mounted () {
      // 监听键盘Esc按键事件
      this.$nextTick(() => {
        // 按下键盘
        document.addEventListener('keydown', (e) => {
          // Esc按键是27
          if (e.keyCode === 27) {
            // 在这里写你的操作逻辑
            this.hide()
          }
        })

        // 去除默认预览图
        // 虽然setDragImage比较鸡肋,但是我们可以设置一张透明的图片就可以实现去除默认预览图的效果了
        document.addEventListener('dragstart', function (ev) {
          let img = new Image()
          img.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' %3E%3Cpath /%3E%3C/svg%3E"
          ev.dataTransfer.setDragImage(img, 0, 0)
        })
      })
    }

  }
</script>

<style scoped lang="scss">
  .back_box {
    position: fixed;
    z-index: 9999;
    cursor: move;
  }

  .drag_box {
    position: fixed;
    overflow: hidden;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
    user-select: none; /* 不可选中,为了拖拽时不让文字高亮 */
    -webkit-user-drag: none;
  }

  .content {
    position: absolute;
    z-index: 88;
    width: 100%;
    padding: 0;
    overflow: hidden;
    font-size: 12px;
    transform-origin: 0 0; /* 用作缩放基点 */
    .title {
      height: 40px;
      padding: 10px;
      font-weight: 600;
      font-size: 14px;
      border-bottom: 1px solid #f5f5f5;
    }
  }

  .sotp {
    position: absolute;
    top: 10px;
    right: 20px;
    z-index: 999;
    width: 30px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    background: #fff;
    border-radius: 50%;
    cursor: pointer;
  }
</style>

原文地址:https://blog.csdn.net/panfu163/article/details/129850376

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_24020.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注