vue3 hoooks 拖拽边框放大缩小

export default function useResize(dragRef, option, emit) {
  const { minWidth, minHeight, headerSize, edgeSize, scale } = option || {
    minWidth: 400,
    minHeight: 500,
    headerSize: 40,
    edgeSize: 10,
    scale: 1
  }

  const bodyStyle = ref({ minWidth, minHeight })

  const isResizing = ref(false)
  const initialPosition = ref({ clientX: 0, clientY: 0 })
  const initialSize = ref({ clientWidth: 0, clientHeight: 0, offsetLeft: 0, offsetTop: 0 })

  const cursorStyle = ref('default')

  const updateCursorStyle = (e) => {
    const { offsetLeft, offsetTop, clientWidth, clientHeight } = dragRef.value
    const { clientX, clientY } = e
    if (
      clientX >= offsetLeft &&
      clientX <= offsetLeft + clientWidth &&
      clientY >= offsetTop &&
      clientY <= offsetTop + headerSize
    ) {
      cursorStyle.value = 'default'
      return
    }
    if (
      clientX > offsetLeft + clientWidth - edgeSize &&
      clientY > offsetTop + clientHeight - edgeSize
    ) {
      cursorStyle.value = 'se-resize' // 右下角
    } else if (clientX < offsetLeft + edgeSize && clientY > offsetTop + clientHeight - edgeSize) {
      cursorStyle.value = 'sw-resize' // 左下角
    } else if (clientX > offsetLeft + clientWidth - edgeSize && clientY < offsetTop + edgeSize) {
      cursorStyle.value = 'ne-resize' // 右上角
    } else if (clientX < offsetLeft + edgeSize && clientY < offsetTop + edgeSize) {
      cursorStyle.value = 'nw-resize' // 左上角
    } else if (clientX > offsetLeft + clientWidth - edgeSize) {
      cursorStyle.value = 'w-resize' // 右拖动
    } else if (offsetLeft + edgeSize > clientX) {
      cursorStyle.value = 'w-resize' // 左拖动
    } else if (clientY > offsetTop + clientHeight - edgeSize) {
      cursorStyle.value = 's-resize' // 下拖动
    } else if (clientY < offsetTop + edgeSize) {
      cursorStyle.value = 's-resize' // 上拖动
    } else {
      cursorStyle.value = 'default' // 默认光标样式
    }
  }

  const onMousedown = (e) => {
    const { offsetLeft, offsetTop, clientWidth, clientHeight } = dragRef.value
    const { clientX, clientY } = e
    isResizing.value = true
    initialPosition.value = { clientX, clientY }
    initialSize.value = {
      offsetLeft,
      offsetTop,
      clientWidth,
      clientHeight
    }
  }

  const onMousemove = (e) => {
    if (isResizing.value && cursorStyle.value !== 'default') {
      e.preventDefault() // 移动时禁用默认事件
      const { offsetLeft, offsetTop, clientWidth, clientHeight } = initialSize.value
      let newWidth = clientWidth
      let newHeight = clientHeight
      let newLeft = offsetLeft
      let newTop = offsetTop
      const { clientX: x, clientY: y } = initialPosition.value
      const { clientX, clientY } = e

      // 左侧鼠标拖拽位置
      if (x > offsetLeft && x < offsetLeft + edgeSize) {
        // 往左拖拽
        if (x > clientX) {
          newWidth = clientWidth + (x - clientX) * scale
        }
        // 往右拖拽
        if (x < clientX) {
          newWidth = Math.max(clientWidth - (clientX - x) * scale, minWidth)
        }
        if (newWidth === minWidth) {
          newLeft = offsetLeft + clientWidth - minWidth
        } else {
          newLeft = offsetLeft + (clientX - x) * scale
        }
      }

      // 右侧鼠标拖拽位置
      if (x > offsetLeft + clientWidth - edgeSize && x < offsetLeft + clientWidth) {
        // 往左拖拽
        if (x > clientX) {
          newWidth = Math.max(clientWidth - (x - clientX) * scale, minWidth)
        }
        // 往右拖拽
        if (x < clientX) {
          newWidth = clientWidth + (clientX - x) * scale
        }
      }

      // 顶部鼠标拖拽位置
      if (y > offsetTop && y < offsetTop + edgeSize) {
        // 往上拖拽
        if (y > clientY) {
          newHeight = clientHeight + (y - clientY) * scale
        }
        // 往下拖拽
        if (y < clientY) {
          newHeight = Math.max(clientHeight - (clientY - y) * scale, minHeight)
        }
        if (newHeight === minHeight) {
          newTop = offsetTop + clientHeight - minHeight
        } else {
          newTop = offsetTop + (clientY - y) * scale
        }
      }

      // 底部鼠标拖拽位置
      if (y > offsetTop + clientHeight - edgeSize && y < offsetTop + clientHeight) {
        // 往上拖拽
        if (y > clientY) {
          newHeight = Math.max(clientHeight - (y - clientY) * scale, minHeight)
        }
        // 往下拖拽
        if (y < clientY) {
          newHeight = clientHeight + (clientY - y) * scale
        }
      }

      if (dragRef.value) {
        bodyStyle.value = { width: `${newWidth}px`, height: `${newHeight}px` }
        emit('resize', { width: newWidth, height: newHeight, left: newLeft, top: newTop })
      }
    } else {
      updateCursorStyle(e)
    }
  }

  const onMouseup = () => {
    isResizing.value = false
  }

  onMounted(() => {
    document.addEventListener('mousemove', onMousemove)
    document.addEventListener('mouseup', onMouseup)
  })

  onUnmounted(() => {
    document.removeEventListener('mousemove', onMousemove)
    document.removeEventListener('mouseup', onMouseup)
  })

  return {
    cursorStyle,
    bodyStyle,
    onMousedown
  }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值