车间能级提升-智能设备管理系统
朱桂飞
2025-01-09 3e8f7f239bedae0b4f04a1ac6bd443ba6298f73c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
 * @copy https://github.com/element-plus/element-plus/blob/dev/packages/hooks/use-draggable/index.ts
 * 调整部分细节
 */
 
import { onBeforeUnmount, onMounted, reactive, ref, watchEffect } from 'vue';
import type { ComputedRef, Ref } 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,
  };
}