From 8c2d75380d87436da025953d3a30c14c6de98298 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 6 Mar 2026 09:44:24 +0100 Subject: [PATCH] fix: smooth globe rotation - only rescale points on zoom change pointRadius was recalculated on every controls change event (including rotation frames), causing 50k+ points to re-render each frame. Now only triggers when altitude changes >5%, keeping rotation smooth. Co-Authored-By: Claude Opus 4.6 --- web/src/plugins/radio/RadioTab.tsx | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/web/src/plugins/radio/RadioTab.tsx b/web/src/plugins/radio/RadioTab.tsx index 1a53a2c..6b2ee53 100644 --- a/web/src/plugins/radio/RadioTab.tsx +++ b/web/src/plugins/radio/RadioTab.tsx @@ -209,18 +209,18 @@ export default function RadioTab({ data }: { data: any }) { controls.autoRotateSpeed = 0.3; } - // Scale point radius based on zoom altitude so points don't overlap when zoomed in - let scaleRafId = 0; - const BASE_ALT = 2.0; // default altitude + // Scale point radius only when zoom (altitude) changes, not during rotation + let lastAlt = 2.0; + const BASE_ALT = 2.0; const onControlsChange = () => { - cancelAnimationFrame(scaleRafId); - scaleRafId = requestAnimationFrame(() => { - const alt = globe.pointOfView().altitude; - const scale = Math.max(0.1, alt / BASE_ALT); - globe.pointRadius((d: any) => { - const base = Math.max(0.12, Math.min(0.45, 0.06 + (d.size ?? 1) * 0.005)); - return base * scale; - }); + const alt = globe.pointOfView().altitude; + // Only recalc when altitude changed significantly (>5%) + if (Math.abs(alt - lastAlt) / lastAlt < 0.05) return; + lastAlt = alt; + const scale = Math.max(0.1, alt / BASE_ALT); + globe.pointRadius((d: any) => { + const base = Math.max(0.12, Math.min(0.45, 0.06 + (d.size ?? 1) * 0.005)); + return base * scale; }); }; controls.addEventListener('change', onControlsChange); @@ -245,7 +245,6 @@ export default function RadioTab({ data }: { data: any }) { return () => { controls.removeEventListener('change', onControlsChange); - cancelAnimationFrame(scaleRafId); el.removeEventListener('mousedown', onInteract); el.removeEventListener('touchstart', onInteract); el.removeEventListener('wheel', onInteract);