Skip to content

fix(web): restore full starfield view after zoom-out#220

Merged
JustAGhosT merged 1 commit into
mainfrom
fix/starfield-zoom-out-recenter
Jun 23, 2026
Merged

fix(web): restore full starfield view after zoom-out#220
JustAGhosT merged 1 commit into
mainfrom
fix/starfield-zoom-out-recenter

Conversation

@JustAGhosT

@JustAGhosT JustAGhosT commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Symptom

After zooming into a focus-area sun and clicking Zoom Out, the starfield looked collapsed to one side — most suns hidden, planets missing, background dimmed, a vignette and the focused sun's orbit ring still showing. It stayed that way (not a transient).

Root cause

The camera was a red herring — instrumented telemetry shows it recenters perfectly to (cx 0.5, cy 0.5, zoom 1) on zoom-out. The real bug: the animation render loop kept rendering in "focused mode" because it read a stale focusedSunId.

focusedSunId is fed to the loop through the animationParams useMemo, which lags focus changes — so props.focusedSunId stayed "…-sun" even after React had cleared focus (the Zoom Out button, gated on focusedSunId, had already unmounted). Focus-mode rendering branches (if (props.focusedSunId)) therefore stayed active:

  • background stars dimmed + star-birthplaces/black-holes hidden,
  • vignette + focus orbit-ring overlays,
  • planet filter showing only the focused sun's planets.

Fix

Sync focusedSunId into a live ref (focusedSunIdRef) on every change — mirroring the existing hoveredSunIdRef pattern in this same component — and have the loop read the ref instead of the memoised prop. Its null (= "no focus") is used directly; it only falls back to the prop if the ref is unwired (defensive). 3 files, +29/-8.

Verification (headless, against the production build)

Clicking the real sun positions to trigger an actual zoom, then the DOM Zoom Out button:

state camera focus (loop) planets rendered
default (0.5, 0.5, 1) null 14 / 14
zoomed into a sun (0.83, 0.43, 1.8) fintech-blockchain-sun 2 / 14
after zoom-out (0.5, 0.5, 1) null 14 / 14

Before the fix the loop reported focus = "…-sun" and 2/14 planets after zoom-out (focus-mode stuck on); after the fix it's null and 14/14, and the screenshot shows the full centred starfield restored.

Note on #219

PR #219 (camera-transform offset fade) was based on a misdiagnosis — the transform was never the cause. It's harmless (identity at the resting state) and left in place; can be reverted separately if desired.

Summary by CodeRabbit

  • Bug Fixes
    • Improved responsiveness of focused-mode rendering in the starfield by ensuring the animation loop reads the latest focus state synchronously, eliminating visual lag when switching between focused suns and preventing state-related display inconsistencies during zoom interactions.

Zooming out from a focused sun left the field looking collapsed to one side —
most suns/planets hidden, background dimmed. The camera actually recentred
correctly to (0.5, 0.5, zoom 1); the bug was that the animation loop kept
rendering in "focused mode" because it read a STALE focusedSunId.

The params memo feeding the loop lags focus changes, so `props.focusedSunId`
stayed set after React had already cleared focus on zoom-out. Read focus from a
live ref instead (synced on every change, mirroring hoveredSunIdRef), so
focus-mode rendering — dimmed background, vignette, and the planet filter that
hid all but the focused sun's planets — clears on zoom-out.

Verified headless: after zoom-out focus=null, camera=(0.5,0.5,1), and all 14
planets render again (was 2/14 while the stale focus persisted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0aa8243b-bc2d-4f04-b7ac-5c2b87cf1b23

📥 Commits

Reviewing files that changed from the base of the PR and between b67d12b and 8934f17.

📒 Files selected for processing (3)
  • apps/web/src/features/layout/components/Starfield/Starfield.tsx
  • apps/web/src/features/layout/components/Starfield/hooks/animation/animate.ts
  • apps/web/src/features/layout/components/Starfield/hooks/animation/types.ts

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


📝 Walkthrough

Walkthrough

Starfield.tsx introduces a focusedSunIdRef kept in sync with focusedSunId via a useEffect, then passes this ref into animationParams. AnimationProps in types.ts gains an optional focusedSunIdRef field. animate.ts derives liveFocusedSunId from the ref each frame, replacing all prior direct reads of props.focusedSunId in rendering conditionals.

Changes

Live focusedSunId ref for animation loop

Layer / File(s) Summary
Ref type contract and wiring into animationParams
apps/web/src/features/layout/components/Starfield/hooks/animation/types.ts, apps/web/src/features/layout/components/Starfield/Starfield.tsx
AnimationProps adds an optional focusedSunIdRef?: MutableRefObject<string | null> field. Starfield creates the ref, syncs it to focusedSunId in an effect, and includes it in the animationParams object passed to the loop.
Animation loop: derive liveFocusedSunId and update all render branches
apps/web/src/features/layout/components/Starfield/hooks/animation/animate.ts
At the top of each frame, liveFocusedSunId is read from focusedSunIdRef.current (falling back to props.focusedSunId if the ref is absent). All five rendering branches—background-star dimming, star-birthplace guard, drawSuns argument, black-hole suppression, and planet-filter cache invalidation—switch from props.focusedSunId to liveFocusedSunId.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 A stale ref once tricked the stars at night,
The focused sun blinked in and out of sight.
Now a useEffect keeps the ref in sync,
Each frame reads live — no lag, no missing link.
The cosmos renders crisp at every blink! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/starfield-zoom-out-recenter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JustAGhosT JustAGhosT merged commit ac09b46 into main Jun 23, 2026
1 of 2 checks passed
@JustAGhosT JustAGhosT deleted the fix/starfield-zoom-out-recenter branch June 23, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant