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 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-06 09:44:24 +01:00
parent 2c0cb7a67a
commit 8c2d75380d

View file

@ -209,18 +209,18 @@ export default function RadioTab({ data }: { data: any }) {
controls.autoRotateSpeed = 0.3; controls.autoRotateSpeed = 0.3;
} }
// Scale point radius based on zoom altitude so points don't overlap when zoomed in // Scale point radius only when zoom (altitude) changes, not during rotation
let scaleRafId = 0; let lastAlt = 2.0;
const BASE_ALT = 2.0; // default altitude const BASE_ALT = 2.0;
const onControlsChange = () => { const onControlsChange = () => {
cancelAnimationFrame(scaleRafId); const alt = globe.pointOfView().altitude;
scaleRafId = requestAnimationFrame(() => { // Only recalc when altitude changed significantly (>5%)
const alt = globe.pointOfView().altitude; if (Math.abs(alt - lastAlt) / lastAlt < 0.05) return;
const scale = Math.max(0.1, alt / BASE_ALT); lastAlt = alt;
globe.pointRadius((d: any) => { const scale = Math.max(0.1, alt / BASE_ALT);
const base = Math.max(0.12, Math.min(0.45, 0.06 + (d.size ?? 1) * 0.005)); globe.pointRadius((d: any) => {
return base * scale; const base = Math.max(0.12, Math.min(0.45, 0.06 + (d.size ?? 1) * 0.005));
}); return base * scale;
}); });
}; };
controls.addEventListener('change', onControlsChange); controls.addEventListener('change', onControlsChange);
@ -245,7 +245,6 @@ export default function RadioTab({ data }: { data: any }) {
return () => { return () => {
controls.removeEventListener('change', onControlsChange); controls.removeEventListener('change', onControlsChange);
cancelAnimationFrame(scaleRafId);
el.removeEventListener('mousedown', onInteract); el.removeEventListener('mousedown', onInteract);
el.removeEventListener('touchstart', onInteract); el.removeEventListener('touchstart', onInteract);
el.removeEventListener('wheel', onInteract); el.removeEventListener('wheel', onInteract);