| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /**
- * @copy https://github.com/element-plus/element-plus/blob/dev/packages/hooks/use-draggable/index.ts
- * 调整部分细节
- */
- import type { ComputedRef, Ref } from 'vue';
- import { onBeforeUnmount, onMounted, reactive, ref, watchEffect } from 'vue';
- import { unrefElement } from '@vueuse/core';
- export function useModalDraggable(
- targetRef: Ref<HTMLElement | undefined>,
- dragRef: Ref<HTMLElement | undefined>,
- draggable: ComputedRef<boolean>,
- ) {
- const transform = reactive({
- offsetX: 0,
- offsetY: 0,
- });
- const dragging = ref(false);
- const onMousedown = (e: MouseEvent) => {
- const downX = e.clientX;
- const downY = e.clientY;
- if (!targetRef.value) {
- return;
- }
- 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;
- 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;
- const onMousemove = (e: MouseEvent) => {
- let moveX = offsetX + e.clientX - downX;
- let moveY = offsetY + e.clientY - downY;
- moveX = Math.min(Math.max(moveX, minLeft), maxLeft);
- moveY = Math.min(Math.max(moveY, minTop), maxTop);
- transform.offsetX = moveX;
- transform.offsetY = moveY;
- if (targetRef.value) {
- targetRef.value.style.transform = `translate(${moveX}px, ${moveY}px)`;
- dragging.value = true;
- }
- };
- const onMouseup = () => {
- dragging.value = false;
- document.removeEventListener('mousemove', onMousemove);
- document.removeEventListener('mouseup', onMouseup);
- };
- document.addEventListener('mousemove', onMousemove);
- document.addEventListener('mouseup', onMouseup);
- };
- const onDraggable = () => {
- const dragDom = unrefElement(dragRef);
- if (dragDom && targetRef.value) {
- dragDom.addEventListener('mousedown', onMousedown);
- }
- };
- const offDraggable = () => {
- const dragDom = unrefElement(dragRef);
- if (dragDom && targetRef.value) {
- dragDom.removeEventListener('mousedown', onMousedown);
- }
- };
- const resetPosition = () => {
- transform.offsetX = 0;
- transform.offsetY = 0;
- const target = unrefElement(targetRef);
- if (target) {
- target.style.transform = 'none';
- }
- };
- onMounted(() => {
- watchEffect(() => {
- if (draggable.value) {
- onDraggable();
- } else {
- offDraggable();
- }
- });
- });
- onBeforeUnmount(() => {
- offDraggable();
- });
- return {
- dragging,
- resetPosition,
- transform,
- };
- }
|