feat(V0.2): 拖动跟手浮层 —— 半透明副本随指针, 原位虚线占位
Docker Build and Push / build-image (push) Successful in 1m5s

- useRowDrag/useHabitDrag 暴露 ghostRef, 拖动激活与移动时直接改
  transform (绕过 React 重渲染, 保证跟手流畅)
- 打卡浮层带颜色点 + 名称; 任务列表浮层带任务名 + 实时目标列名
- 原位卡片降为低透明度虚线占位, 落点指示不变
This commit is contained in:
jif2.zhang
2026-10-25 01:42:29 +08:00
parent 215263bf2f
commit 83cc218c5e
5 changed files with 54 additions and 5 deletions
+10 -1
View File
@@ -33,6 +33,12 @@ export default function useRowDrag({ columns, onDrop }) {
/** 拖动刚结束 (350ms 内): 抑制松手合成的 click 误开详情页 */
const justEnded = useCallback(() => Date.now() - lastEnd.current < 350, [])
// 跟手浮层: 消费方渲染 <div ref={ghostRef}>, 拖动时直接改 transform
const ghostRef = useRef(null)
const moveGhost = (x, y) => {
if (ghostRef.current) ghostRef.current.style.transform = `translate(${x}px, ${y}px) translate(-50%, -110%)`
}
const onMove = (ev) => {
const s = st.current
if (!s.active) {
@@ -42,6 +48,7 @@ export default function useRowDrag({ columns, onDrop }) {
return
}
ev.preventDefault()
moveGhost(ev.clientX, ev.clientY)
const to = Math.max(0, Math.min(ordered.length - 1, s.fromIdx + Math.round((ev.clientX - s.startX) / STEP)))
if (to !== s.toIdx) {
s.toIdx = to
@@ -99,6 +106,7 @@ export default function useRowDrag({ columns, onDrop }) {
st.current.active = true
if (navigator.vibrate) navigator.vibrate(15)
setDrag({ task, fromIdx, toIdx: fromIdx })
moveGhost(st.current.startX, st.current.startY)
}, 400)
armListeners(ev)
},
@@ -120,11 +128,12 @@ export default function useRowDrag({ columns, onDrop }) {
st.current.active = true
if (navigator.vibrate) navigator.vibrate(15)
setDrag({ task, fromIdx, toIdx: fromIdx })
moveGhost(st.current.startX, st.current.startY)
armListeners(ev, true)
},
onContextMenu: (ev) => ev.preventDefault(),
// eslint-disable-next-line react-hooks/exhaustive-deps
}), [ordered, onDrop])
return { drag, bind, bindHandle, cancel: cleanup, justEnded }
return { drag, bind, bindHandle, ghostRef, cancel: cleanup, justEnded }
}