-
Notifications
You must be signed in to change notification settings - Fork 515
Fix globe drag not ending when pointer released outside element #1447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1024,6 +1024,31 @@ function GlobeSectionInner({ countryData, totalUsers, activeUsersByCountry, sate | |
| }; | ||
| }, [globeReady, mounted, liveAvatars]); | ||
|
|
||
| // When the pointer leaves the globe canvas and the button is released | ||
| // outside, OrbitControls may miss the pointerup (pointer capture can be | ||
| // lost intermittently). Listen on window and forward the event to the | ||
| // canvas so the controls properly end the drag. | ||
| useEffect(() => { | ||
| if (!globeReady) return; | ||
| const domElement = globeRef.current?.renderer().domElement; | ||
| if (!domElement) return; | ||
|
|
||
| const handleWindowPointerUp = (e: PointerEvent) => { | ||
| if (e.target !== domElement && !domElement.contains(e.target as Node)) { | ||
| domElement.dispatchEvent(new PointerEvent('pointerup', { | ||
| pointerId: e.pointerId, | ||
| pointerType: e.pointerType, | ||
| bubbles: true, | ||
| })); | ||
| } | ||
| }; | ||
|
|
||
| window.addEventListener('pointerup', handleWindowPointerUp); | ||
| return () => { | ||
| window.removeEventListener('pointerup', handleWindowPointerUp); | ||
| }; | ||
| }, [globeReady]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stale canvas in pointerup handlerMedium Severity The window Reviewed by Cursor Bugbot for commit 714f60d. Configure here. |
||
|
|
||
| // set globeReady to true after a bit in case onGlobeReady was not called | ||
| useEffect(() => { | ||
| const timeout = setTimeout(() => { | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bubbles: trueis not needed here and has a subtle downside. OrbitControls attaches itspointeruplistener directly ondomElement(not a parent), so bubbling isn't required for it to fire. Withbubbles: true, the synthetic event propagates up through the entire DOM after OrbitControls handles it, triggering any intermediatepointeruplisteners (e.g. React synthetic event delegation atdocument) and re-enteringhandleWindowPointerUponwindow— where it's a no-op due to the target check, but still an unnecessary invocation. Usingbubbles: falsekeeps the dispatch scoped to the canvas and avoids unexpected side-effects.Prompt To Fix With AI