Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/components/Vue3DraggableResizable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ const VdrProps = {
lockAspectRatio: {
type: Boolean,
default: false
},
//开启冲突检测-默认开启
isConflictCheck: {
type: Boolean,
default: true
}
}

Expand Down Expand Up @@ -177,6 +182,7 @@ const VueDraggableResizable = defineComponent({
containerProps,
limitProps,
toRef(props, 'draggable'),
toRef(props, 'isConflictCheck'),
emit,
containerProvider,
parentSize
Expand Down
47 changes: 47 additions & 0 deletions src/components/conflict.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
function formatTransformVal(tl:string, tt:string) {
let left = Number(tl.replace('px', ''))
let top = Number(tt.replace('px', ''))
return [left, top]
}
export function conflict(top:number, left:number, width:number, height:number, nodes:any, oneself:any) {
for (const item of nodes) {
//去除无用text元素及自身dom元素进行对比
if (item.className !== undefined && !item.className.includes(oneself.className)) {
const tw = item.offsetWidth
const th = item.offsetHeight
// 获取left与right
const [tl, tt] = formatTransformVal(item.style.left, item.style.top)
// 左上角与右下角重叠
const tfAndBr =
(top >= tt && left >= tl && tt + th > top && tl + tw > left) ||
(top <= tt && left < tl && top + height > tt && left + width > tl)
// 右上角与左下角重叠
const brAndTf =
(left <= tl && top >= tt && left + width > tl && top < tt + th) ||
(top < tt && left > tl && top + height > tt && left < tl + tw)
// 下边与上边重叠
const bAndT =
(top <= tt && left >= tl && top + height > tt && left < tl + tw) ||
(top >= tt && left <= tl && top < tt + th && left > tl + tw)
// 上边与下边重叠(宽度不一样)
const tAndB =
(top <= tt && left >= tl && top + height > tt && left < tl + tw) ||
(top >= tt && left <= tl && top < tt + th && left > tl + tw)
// 左边与右边重叠
const lAndR =
(left >= tl && top >= tt && left < tl + tw && top < tt + th) ||
(top > tt && left <= tl && left + width > tl && top < tt + th)
// 左边与右边重叠(高度不一样)
const rAndL =
(top <= tt && left >= tl && top + height > tt && left < tl + tw) ||
(top >= tt && left <= tl && top < tt + th && left + width > tl)

// // 如果冲突,就返回状态
if (tfAndBr || brAndTf || bAndT || tAndB || lAndR || rAndL) {
return true
} else {
return false
}
}
}
}
21 changes: 20 additions & 1 deletion src/components/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { onMounted, onUnmounted, ref, watch, Ref, computed } from 'vue'
import { conflict } from './conflict'
import {
getElSize,
filterHandles,
Expand Down Expand Up @@ -233,12 +234,19 @@ function getPosition(e: HandleEvent) {
return [e.pageX, e.pageY]
}
}

//存储初始值
const handleDownOptions = {
left: 0,
top: 0,
width: 0,
height: 0
}
export function initDraggableContainer(
containerRef: Ref<HTMLElement | undefined>,
containerProps: ReturnType<typeof initState>,
limitProps: ReturnType<typeof initLimitSizeAndMethods>,
draggable: Ref<boolean>,
isConflictCheck: Ref<boolean>,
emit: any,
containerProvider: ContainerProvider | null,
parentSize: ReturnType<typeof initParent>
Expand Down Expand Up @@ -267,6 +275,12 @@ export function initDraggableContainer(
}
}
const handleUp = () => {
//调用冲突检测方法
const isConflict = conflict(y.value, x.value, w.value, h.value, containerRef.value!.parentNode!.childNodes, containerRef.value!)
//判断有无冲突和是否开启冲突检测
if(isConflict && isConflictCheck.value){
emit('dragging', { x: setLeft(handleDownOptions.left), y: setTop(handleDownOptions.top) })
}
setDragging(false)
// document.documentElement.removeEventListener('mouseup', handleUp)
// document.documentElement.removeEventListener('mousemove', handleDrag)
Expand Down Expand Up @@ -343,6 +357,11 @@ export function initDraggableContainer(
emit('dragging', { x: setLeft(newLeft), y: setTop(newTop) })
}
const handleDown = (e: HandleEvent) => {
//按下记录组件原始位置及大小
handleDownOptions.left = x.value
handleDownOptions.top = y.value
handleDownOptions.width = w.value
handleDownOptions.height = h.value
if (!draggable.value) return
setDragging(true)
lstX = x.value
Expand Down