| | |
| | | import type { Ref } from 'vue'; |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | export type UseDragOptions = { |
| | | target: HTMLElement; |
| | | onDrag: (e: MouseEvent) => void; |
| | | onDragEnd: (e: MouseEvent) => void; |
| | | /** |
| | | * 拖拽手柄元素的选择器 |
| | | */ |
| | | handle?: string | HTMLElement | Ref<HTMLElement>; |
| | | }; |
| | | export const useDrag = () => { |
| | | |
| | | const getHandleElement = (handle: string | HTMLElement | Ref<HTMLElement>) => { |
| | | if (!handle) return null; |
| | | if (typeof handle === 'string') { |
| | | return document.querySelector(handle); |
| | | } else if (handle instanceof HTMLElement) { |
| | | return handle; |
| | | } else if (typeof handle === 'object' && 'value' in handle) { |
| | | return handle.value; |
| | | } |
| | | return null; |
| | | }; |
| | | |
| | | export const useDrag = (options: UseDragOptions = {}) => { |
| | | const { handle } = options; |
| | | const isDragging = ref(false); |
| | | const startPos = ref({ x: 0, y: 0 }); |
| | | const offset = ref({ x: 0, y: 0 }); |
| | | const startDrag = (e: MouseEvent) => { |
| | | // 如果设置了handle,则判断事件源是否是handle元素或其子元素 |
| | | if (handle) { |
| | | const handleElement = getHandleElement(handle); |
| | | if (!handleElement?.contains(e.target as Node)) { |
| | | return; |
| | | } |
| | | } |
| | | isDragging.value = true; |
| | | startPos.value = { |
| | | x: e.clientX - offset.value.x, |
| | |
| | | document.addEventListener('mousemove', handleMouseMove); |
| | | document.addEventListener('mouseup', handleMouseUp); |
| | | }; |
| | | const handleStyle = computed(() => { |
| | | return handle |
| | | ? { |
| | | cursor: isDragging.value ? 'grabbing' : 'grab', |
| | | } |
| | | : {}; |
| | | }); |
| | | |
| | | const style = computed( |
| | | () => |
| | | ({ |
| | | position: 'absolute', |
| | | transform: `translate(${offset.value.x}px, ${offset.value.y}px)`, |
| | | ...(handle |
| | | ? {} |
| | | : { |
| | | cursor: isDragging.value ? 'grabbing' : 'grab', |
| | | }), |
| | | } as any) |
| | | ); |
| | | |
| | | |
| | | return { |
| | | isDragging, |
| | | startDrag, |
| | | style, |
| | | handleStyle, |
| | | }; |
| | | }; |