fix: 改为DOM直驱拖拽跟随减少卡顿

This commit is contained in:
JSR
2026-03-26 16:37:56 +08:00
parent 2c58983b14
commit c7c059cd63
+26 -12
View File
@@ -108,9 +108,7 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
const [pointerDraggingStudentId, setPointerDraggingStudentId] = useState<number | null>(null) const [pointerDraggingStudentId, setPointerDraggingStudentId] = useState<number | null>(null)
const [pointerTargetGroup, setPointerTargetGroup] = useState<string | null>(null) const [pointerTargetGroup, setPointerTargetGroup] = useState<string | null>(null)
const [pointerDragStudentName, setPointerDragStudentName] = useState("") const [pointerDragStudentName, setPointerDragStudentName] = useState("")
const [pointerDragPosition, setPointerDragPosition] = useState<{ x: number; y: number } | null>( const pointerDragGhostRef = useRef<HTMLDivElement | null>(null)
null
)
const pointerDragPositionRef = useRef<{ x: number; y: number } | null>(null) const pointerDragPositionRef = useRef<{ x: number; y: number } | null>(null)
const pointerDragRafRef = useRef<number | null>(null) const pointerDragRafRef = useRef<number | null>(null)
const draggingStudentIdRef = useRef<number | null>(null) const draggingStudentIdRef = useRef<number | null>(null)
@@ -510,7 +508,14 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
setPointerDraggingStudentId(studentId) setPointerDraggingStudentId(studentId)
setPointerDragStudentName(studentName) setPointerDragStudentName(studentName)
pointerDragPositionRef.current = { x: e.clientX, y: e.clientY } pointerDragPositionRef.current = { x: e.clientX, y: e.clientY }
setPointerDragPosition({ x: e.clientX, y: e.clientY }) requestAnimationFrame(() => {
if (!pointerDragPositionRef.current) return
const ghost = pointerDragGhostRef.current
if (!ghost) return
ghost.style.transform = `translate3d(${pointerDragPositionRef.current.x + 14}px, ${
pointerDragPositionRef.current.y + 14
}px, 0)`
})
setPointerTargetGroup(null) setPointerTargetGroup(null)
e.currentTarget.setPointerCapture(e.pointerId) e.currentTarget.setPointerCapture(e.pointerId)
console.debug("[GroupBoard] pointer drag start", { console.debug("[GroupBoard] pointer drag start", {
@@ -526,10 +531,11 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
pointerDragRafRef.current = requestAnimationFrame(() => { pointerDragRafRef.current = requestAnimationFrame(() => {
pointerDragRafRef.current = null pointerDragRafRef.current = null
if (!pointerDragPositionRef.current) return if (!pointerDragPositionRef.current) return
setPointerDragPosition({ const ghost = pointerDragGhostRef.current
x: pointerDragPositionRef.current.x, if (!ghost) return
y: pointerDragPositionRef.current.y, ghost.style.transform = `translate3d(${pointerDragPositionRef.current.x + 14}px, ${
}) pointerDragPositionRef.current.y + 14
}px, 0)`
}) })
} }
@@ -570,8 +576,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
} }
setPointerDraggingStudentId(null) setPointerDraggingStudentId(null)
setPointerDragStudentName("") setPointerDragStudentName("")
setPointerDragPosition(null)
setPointerTargetGroup(null) setPointerTargetGroup(null)
const ghost = pointerDragGhostRef.current
if (ghost) ghost.style.transform = "translate3d(-9999px, -9999px, 0)"
} }
const readFileAsDataUrl = (file: File): Promise<string> => { const readFileAsDataUrl = (file: File): Promise<string> => {
@@ -1411,9 +1418,15 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
draggingStudentIdRef.current = null draggingStudentIdRef.current = null
pointerDragSourceGroupRef.current = null pointerDragSourceGroupRef.current = null
pointerDragTargetGroupRef.current = null pointerDragTargetGroupRef.current = null
pointerDragPositionRef.current = null
if (pointerDragRafRef.current != null) {
cancelAnimationFrame(pointerDragRafRef.current)
pointerDragRafRef.current = null
}
const ghost = pointerDragGhostRef.current
if (ghost) ghost.style.transform = "translate3d(-9999px, -9999px, 0)"
setPointerDraggingStudentId(null) setPointerDraggingStudentId(null)
setPointerDragStudentName("") setPointerDragStudentName("")
setPointerDragPosition(null)
setPointerTargetGroup(null) setPointerTargetGroup(null)
}} }}
onOk={handleSaveGroupBoard} onOk={handleSaveGroupBoard}
@@ -1530,8 +1543,9 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
) )
})} })}
</div> </div>
{pointerDraggingStudentId != null && pointerDragPosition && ( {pointerDraggingStudentId != null && (
<div <div
ref={pointerDragGhostRef}
style={{ style={{
position: "fixed", position: "fixed",
left: 0, left: 0,
@@ -1549,7 +1563,7 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
whiteSpace: "nowrap", whiteSpace: "nowrap",
overflow: "hidden", overflow: "hidden",
textOverflow: "ellipsis", textOverflow: "ellipsis",
transform: `translate3d(${pointerDragPosition.x + 14}px, ${pointerDragPosition.y + 14}px, 0)`, transform: "translate3d(-9999px, -9999px, 0)",
willChange: "transform", willChange: "transform",
}} }}
> >