From 0bc8242064c703fc9433240f229f2d3d57286eec Mon Sep 17 00:00:00 2001 From: zhangheng Date: Fri, 17 Apr 2026 19:26:51 +0800 Subject: [PATCH] fix(tool): middleMouse --- .../label/components/PaperContainer.tsx | 87 +++++++++++++------ 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/components/label/components/PaperContainer.tsx b/components/label/components/PaperContainer.tsx index 05263b5..d354a2b 100644 --- a/components/label/components/PaperContainer.tsx +++ b/components/label/components/PaperContainer.tsx @@ -518,7 +518,7 @@ const PaperContainer = ( token: number imageName: string } | null>(null) - const renderModePanRef = useRef({ + const middleMousePanRef = useRef({ active: false, lastX: 0, lastY: 0, @@ -2343,42 +2343,72 @@ const PaperContainer = ( syncRenderModeVisuals, ]) - const stopRenderModePan = useCallback(() => { - renderModePanRef.current.active = false + const hidePaperContextMenu = useCallback(() => { + useOtherToolsStore.getState().setShowContextMenu({ + showContextMenu: false, + position: { top: 0, left: 0 }, + imageId: "", + operationId: "", + id: 0, + }) }, []) + const startMiddleMousePan = useCallback( + (clientX: number, clientY: number) => { + middleMousePanRef.current = { + active: true, + lastX: clientX, + lastY: clientY, + } + }, + [] + ) + + const stopMiddleMousePan = useCallback(() => { + middleMousePanRef.current.active = false + }, []) + + useEffect(() => { + const container = containerRef.current + if (!container) return + + const handleMouseDownCapture = (event: MouseEvent) => { + if (event.button !== 1) return + + const target = event.target as HTMLElement | null + if (target?.closest('[data-label-context-menu="true"]')) return + + event.preventDefault() + event.stopPropagation() + hidePaperContextMenu() + startMiddleMousePan(event.clientX, event.clientY) + } + + container.addEventListener("mousedown", handleMouseDownCapture, true) + + return () => { + container.removeEventListener("mousedown", handleMouseDownCapture, true) + stopMiddleMousePan() + } + }, [hidePaperContextMenu, startMiddleMousePan, stopMiddleMousePan]) + const handleRenderModeOverlayMouseDown = useCallback( (event: React.MouseEvent) => { event.preventDefault() event.stopPropagation() - useOtherToolsStore.getState().setShowContextMenu({ - showContextMenu: false, - position: { top: 0, left: 0 }, - imageId: "", - operationId: "", - id: 0, - }) + hidePaperContextMenu() if (event.button !== 1) return - renderModePanRef.current = { - active: true, - lastX: event.clientX, - lastY: event.clientY, - } + startMiddleMousePan(event.clientX, event.clientY) }, - [] + [hidePaperContextMenu, startMiddleMousePan] ) useEffect(() => { - if (!renderMode) { - stopRenderModePan() - return - } - const handleMouseMove = (event: MouseEvent) => { - const currentPan = renderModePanRef.current + const currentPan = middleMousePanRef.current if (!currentPan.active) return event.preventDefault() @@ -2390,26 +2420,29 @@ const PaperContainer = ( if (!deltaX && !deltaY) return group.position = group.position.add(new paper.Point(deltaX, deltaY)) - renderModePanRef.current.lastX = event.clientX - renderModePanRef.current.lastY = event.clientY + middleMousePanRef.current.lastX = event.clientX + middleMousePanRef.current.lastY = event.clientY } const handleMouseUp = (event: MouseEvent) => { if (event.button === 1) { event.preventDefault() } - stopRenderModePan() + + stopMiddleMousePan() } window.addEventListener("mousemove", handleMouseMove, { passive: false }) window.addEventListener("mouseup", handleMouseUp, { passive: false }) + window.addEventListener("blur", stopMiddleMousePan) return () => { window.removeEventListener("mousemove", handleMouseMove) window.removeEventListener("mouseup", handleMouseUp) - stopRenderModePan() + window.removeEventListener("blur", stopMiddleMousePan) + stopMiddleMousePan() } - }, [renderMode, stopRenderModePan]) + }, [stopMiddleMousePan]) const getTargetGroupPosition = useCallback( ({