import { useDraggable } from '@vueuse/core' import { ref } from 'vue' export function useIconDrag(el: HTMLElement, container: HTMLElement) { let offsetX = 0 let offsetY = 0 let containerRect = container.getBoundingClientRect() el.addEventListener('mousedown', (e) => { el.classList.add('dragging') let rect = el.getBoundingClientRect() console.log(rect) offsetX = e.clientX - rect.left offsetY = e.clientY - rect.top // 临时脱离 grid,用绝对定位移动 el.style.position = "absolute"; el.style.left = rect.left - containerRect.left + "px"; el.style.top = rect.top - containerRect.top + "px"; el.style.gridRow = "auto"; el.style.gridColumn = "auto"; document.addEventListener("mousemove", onMouseMove); document.addEventListener("mouseup", onMouseUp); }) function onMouseMove(e: MouseEvent) { if (!el) return; el.style.left = e.clientX - containerRect.left - offsetX + "px"; el.style.top = e.clientY - containerRect.top - offsetY + "px"; } function onMouseUp(e: MouseEvent) { if (!el) return; const cellWidth = 90 + 16; // 图标宽度 + gap const cellHeight = 110 + 16; // 计算所在行列 let col = Math.round((e.clientX - containerRect.left) / cellWidth) + 1; let row = Math.round((e.clientY - containerRect.top) / cellHeight) + 1; // 限制在 grid 内 const maxCols = Math.floor(containerRect.width / cellWidth); const maxRows = Math.floor(containerRect.height / cellHeight); col = Math.max(1, Math.min(maxCols, col)); row = Math.max(1, Math.min(maxRows, row)); console.log(col, row) // 放回 grid el.style.position = "relative"; el.style.left = ""; el.style.top = ""; el.style.gridRow = `${row}`; el.style.gridColumn = `${col}`; el.classList.remove("dragging"); document.removeEventListener("mousemove", onMouseMove); document.removeEventListener("mouseup", onMouseUp); } }