From 981a01a191352b24c9119f2abbc617c206357133 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 25 May 2026 19:48:29 +0800 Subject: [PATCH] fix: allow 3d orbit during hotspot placement --- components/canvas/world3d/World3DViewer.tsx | 34 +++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/components/canvas/world3d/World3DViewer.tsx b/components/canvas/world3d/World3DViewer.tsx index 3950b253c..dedb0e450 100644 --- a/components/canvas/world3d/World3DViewer.tsx +++ b/components/canvas/world3d/World3DViewer.tsx @@ -1106,6 +1106,7 @@ function WorldSplatScene({ const camera = useThree((state) => state.camera); const renderer = useThree((state) => state.gl); const orbitControlsRef = useRef(null); + const hotspotPointerDownRef = useRef<{ x: number; y: number } | null>(null); const hasAppliedInitialViewRef = useRef(false); const lastCameraPoseRef = useRef(null); const lastResetViewTokenRef = useRef(resetViewToken); @@ -1365,8 +1366,32 @@ function WorldSplatScene({ sparkRenderer.dirty = true; }); - const handlePointerDown = (event: ThreeEvent) => { + useEffect(() => { + hotspotPointerDownRef.current = null; + }, [interactionMode, splatUrl]); + + const handleHotspotPointerDown = (event: ThreeEvent) => { if (interactionMode !== "hotspot") return; + hotspotPointerDownRef.current = { + x: event.nativeEvent.clientX, + y: event.nativeEvent.clientY, + }; + }; + + const handleHotspotPointerMove = (event: ThreeEvent) => { + if (interactionMode !== "hotspot" || !hotspotPointerDownRef.current) return; + const deltaX = event.nativeEvent.clientX - hotspotPointerDownRef.current.x; + const deltaY = event.nativeEvent.clientY - hotspotPointerDownRef.current.y; + if (Math.hypot(deltaX, deltaY) > 6) { + hotspotPointerDownRef.current = null; + } + }; + + const handleHotspotClick = (event: ThreeEvent) => { + if (interactionMode !== "hotspot") return; + const pointerDown = hotspotPointerDownRef.current; + hotspotPointerDownRef.current = null; + if (!pointerDown) return; event.stopPropagation(); onPick?.({ point: [event.point.x, event.point.y, event.point.z], @@ -1387,7 +1412,12 @@ function WorldSplatScene({ ) : null} - + {particleCloudData ? : null}