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
}
}
vue3 hoooks 拖拽边框放大缩小
最新推荐文章于 2024-07-16 17:18:30 发布