vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue项目弹窗拖拽、缩放功能

vue项目中弹窗拖拽、缩放功能实现过程

作者:Qredsun

文章介绍了如何在项目中实现会话窗口的拖拽和缩放功能,包括指定拖拽的窗口和区域、缩放的对象和区域,以及如何添加指定区域和改变鼠标样式

背景

在项目中有一个会话窗口,需要支持用户拖拽、缩放的功能

实现

拖拽

指定要拖拽的窗口

// 拖拽 <div ref="resizableBox" ><div class="header"></div></div>
const visible = ref(false)
const position = ref({ x: 200, y: 100 })
const emit = defineEmits(['update:visible', 'closeDialog'])

let dragging = false
let offsetX, offsetY, maxLeft, maxTop

const startDrag = (e) => {
  dragging = true
  offsetX = e.clientX - position.value.x
  offsetY = e.clientY - position.value.y
  document.body.style.userSelect = 'none'; // 防止选中文本

  document.addEventListener('mousemove', onDrag)
  document.addEventListener('mouseup', stopDrag)
}

const onDrag = (e) => {
  if (!dragging) return
  position.value.x = Math.max(0, Math.min(maxLeft,(e.clientX - offsetX)))
  position.value.y = Math.max(0, Math.min(maxTop,(e.clientY - offsetY)))
  console.log(maxLeft,position.value.x,maxTop,position.value.y)
}

const stopDrag = () => {
  dragging = false
  document.removeEventListener('mousemove', onDrag)
  document.removeEventListener('mouseup', stopDrag)
}


const initDialogPosition = () => {
  // 初始居中:等待 DOM 渲染后计算中心点
  nextTick(() => {
    const dialog = document.querySelector('.header')
    if (dialog) {
      const { innerWidth, innerHeight } = window
      const { offsetWidth, offsetHeight } = dialog as HTMLElement
      maxLeft = innerWidth - offsetWidth
      maxTop = innerHeight - Math.max(560, offsetHeight)
      position.value.x = maxLeft / 2
      position.value.y = maxTop / 3
      console.log('innerWidth', innerWidth, innerHeight)
      console.log('dialog', dialog.getBoundingClientRect())
    }
  })
}

指定拖拽的区域

const initDialogPosition = () => {
  // 初始居中:等待 DOM 渲染后计算中心点
  nextTick(() => {
    const dialog = document.querySelector('.header')
    if (dialog) {
      const { innerWidth, innerHeight } = window
      const { offsetWidth, offsetHeight } = dialog as HTMLElement
      maxLeft = innerWidth - offsetWidth
      maxTop = innerHeight - Math.max(560, offsetHeight)
      position.value.x = maxLeft / 2
      position.value.y = maxTop / 3
      console.log('innerWidth', innerWidth, innerHeight)
      console.log('dialog', dialog.getBoundingClientRect())
    }
  })
}

缩放

指定缩放的对象

// 缩放  <div ref="resizableBox" ><div class="resizer" @mousedown="initResize"></div></div>
const resizableBox = ref<HTMLElement | null>(null);

function initResize(e: MouseEvent) {
  const box = resizableBox.value;
  if (!box) return;

  const startX = e.clientX;
  const startY = e.clientY;
  const startWidth = box.offsetWidth;
  const startHeight = box.offsetHeight;

  function onMouseMove(event: MouseEvent) {
    const newWidth = Math.max(400, startWidth + (event.clientX - startX));
    const newHeight = Math.max(560, startHeight + (event.clientY - startY));
    box.style.width = `${newWidth}px`;
    box.style.height = `${newHeight}px`;
  }

  function onMouseUp() {
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('mouseup', onMouseUp);
  }

  document.addEventListener('mousemove', onMouseMove);
  document.addEventListener('mouseup', onMouseUp);
}

也可以添加指定区域,实现鼠标样式转变

.resizer {
  width: 14px;
  height: 14px;
  position: absolute;
  right: 0;
  bottom: 0;
  cursor: se-resize;
  z-index: 10;
  border-radius: 2px;
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文