From 58c151e2b0b11a5014af2520bc5182c88f3bd5ac Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Mon, 9 Mar 2026 16:15:38 +0100 Subject: [PATCH] Fix Globe glitches: stop resizing buffer every frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Set canvas size once on mount instead of every render frame - Use actual devicePixelRatio (capped at 2) instead of hardcoded 2 - Remove redundant width*2 doubling (was 4x with devicePixelRatio:2) - Increase spring damping 50→60, reduce stiffness 80→60 for smoother drag --- components/dashboard/Globe.tsx | 35 +++++++++------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/components/dashboard/Globe.tsx b/components/dashboard/Globe.tsx index 0f64304..59380b9 100644 --- a/components/dashboard/Globe.tsx +++ b/components/dashboard/Globe.tsx @@ -16,7 +16,6 @@ interface GlobeProps { export default function Globe({ data, className }: GlobeProps) { const canvasRef = useRef(null) const phiRef = useRef(0) - const widthRef = useRef(0) const pointerInteracting = useRef(null) const pointerInteractionMovement = useRef(0) const { resolvedTheme } = useTheme() @@ -39,8 +38,8 @@ export default function Globe({ data, className }: GlobeProps) { const r = useMotionValue(0) const rs = useSpring(r, { mass: 1, - damping: 50, - stiffness: 80, + damping: 60, + stiffness: 60, }) const updatePointerInteraction = (value: number | null) => { @@ -61,20 +60,13 @@ export default function Globe({ data, className }: GlobeProps) { useEffect(() => { if (!canvasRef.current) return - const onResize = () => { - if (canvasRef.current) { - widthRef.current = canvasRef.current.offsetWidth - } - } + const size = canvasRef.current.offsetWidth + const pixelRatio = Math.min(window.devicePixelRatio, 2) - window.addEventListener('resize', onResize) - onResize() - - const config: COBEOptions = { - width: widthRef.current * 2, - height: widthRef.current * 2, - onRender: () => {}, - devicePixelRatio: 2, + const globe = createGlobe(canvasRef.current, { + width: size * pixelRatio, + height: size * pixelRatio, + devicePixelRatio: pixelRatio, phi: 0, theta: 0.3, dark: isDark ? 1 : 0, @@ -85,19 +77,11 @@ export default function Globe({ data, className }: GlobeProps) { markerColor: [253 / 255, 94 / 255, 15 / 255], glowColor: isDark ? [0.15, 0.15, 0.15] : [1, 1, 1], markers, - } - - const globe = createGlobe(canvasRef.current, { - ...config, - width: widthRef.current * 2, - height: widthRef.current * 2, onRender: (state) => { if (!pointerInteracting.current) phiRef.current += 0.002 state.phi = phiRef.current + rs.get() - state.width = widthRef.current * 2 - state.height = widthRef.current * 2 }, - }) + } as COBEOptions) setTimeout(() => { if (canvasRef.current) canvasRef.current.style.opacity = '1' @@ -105,7 +89,6 @@ export default function Globe({ data, className }: GlobeProps) { return () => { globe.destroy() - window.removeEventListener('resize', onResize) } }, [rs, markers, isDark])