feat: optimize modal dragging range(#6414)

* 当弹窗指定了容器时,拖拽将被限制在容器范围内
pull/162/head^2^2
yuhengshen 2025-06-24 17:05:59 +08:00 committed by GitHub
parent 986eacae9a
commit 946f91f387
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 13 deletions

View File

@ -105,10 +105,17 @@ const shouldDraggable = computed(
() => draggable.value && !shouldFullscreen.value && header.value,
);
const getAppendTo = computed(() => {
return appendToMain.value
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
: undefined;
});
const { dragging, transform } = useModalDraggable(
dialogRef,
headerRef,
shouldDraggable,
getAppendTo,
);
const firstOpened = ref(false);
@ -198,11 +205,6 @@ function handleFocusOutside(e: Event) {
e.preventDefault();
e.stopPropagation();
}
const getAppendTo = computed(() => {
return appendToMain.value
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
: undefined;
});
const getForceMount = computed(() => {
return !unref(destroyOnClose) && unref(firstOpened);

View File

@ -13,6 +13,7 @@ export function useModalDraggable(
targetRef: Ref<HTMLElement | undefined>,
dragRef: Ref<HTMLElement | undefined>,
draggable: ComputedRef<boolean>,
containerSelector?: ComputedRef<string | undefined>,
) {
const transform = reactive({
offsetX: 0,
@ -30,20 +31,36 @@ export function useModalDraggable(
}
const targetRect = targetRef.value.getBoundingClientRect();
const { offsetX, offsetY } = transform;
const targetLeft = targetRect.left;
const targetTop = targetRect.top;
const targetWidth = targetRect.width;
const targetHeight = targetRect.height;
let containerRect: DOMRect | null = null;
if (containerSelector?.value) {
const container = document.querySelector(containerSelector.value);
if (container) {
containerRect = container.getBoundingClientRect();
}
}
let maxLeft, maxTop, minLeft, minTop;
if (containerRect) {
minLeft = containerRect.left - targetLeft + offsetX;
maxLeft = containerRect.right - targetLeft - targetWidth + offsetX;
minTop = containerRect.top - targetTop + offsetY;
maxTop = containerRect.bottom - targetTop - targetHeight + offsetY;
} else {
const docElement = document.documentElement;
const clientWidth = docElement.clientWidth;
const clientHeight = docElement.clientHeight;
const minLeft = -targetLeft + offsetX;
const minTop = -targetTop + offsetY;
const maxLeft = clientWidth - targetLeft - targetWidth + offsetX;
const maxTop = clientHeight - targetTop - targetHeight + offsetY;
minLeft = -targetLeft + offsetX;
minTop = -targetTop + offsetY;
maxLeft = clientWidth - targetLeft - targetWidth + offsetX;
maxTop = clientHeight - targetTop - targetHeight + offsetY;
}
const onMousemove = (e: MouseEvent) => {
let moveX = offsetX + e.clientX - downX;