Skip to content

Redesign beat indicator with cursor and dual target zones#118

Merged
Azuretier merged 3 commits intomainfrom
claude/fix-beat-bar-NHGOZ
Feb 7, 2026
Merged

Redesign beat indicator with cursor and dual target zones#118
Azuretier merged 3 commits intomainfrom
claude/fix-beat-bar-NHGOZ

Conversation

@Azuretier
Copy link
Owner

Summary

Redesigned the beat timing indicator bar from a fill-based progress bar to a cursor-based system with dual on-beat target zones. The cursor now sweeps left-to-right across the bar, glowing gold when positioned within the valid hit window (phase 0–15% or 75–100%).

Key Changes

  • Beat bar UI overhaul: Replaced single beatFill element with:

    • beatTargetLeft: Left zone (0–15% phase) marking early on-beat window
    • beatTargetRight: Right zone (75–100% phase) marking late on-beat window
    • beatCursor: Moving indicator that glows when inside either zone
  • Cursor positioning: Changed from width-based fill to left positioning with translateX(-50%) for precise frame-aligned movement

  • Visual feedback: Added gold glow effect (#FFD700 with box-shadow) when cursor enters on-beat zones, improving hit-timing clarity

  • Ref ordering fix: In beat phase animation, now updates beatPhaseRef before setBeatPhase to ensure ref is current for frame-precise game logic judgments

  • Styling refinements:

    • Increased bar height (16px → 20px on desktop, 10px → 14px on mobile)
    • Reduced background opacity for subtler appearance
    • Added descriptive comments explaining cursor sweep and target zone logic
    • Removed transition on cursor for frame-perfect positioning
  • Component updates: Applied consistent changes across Rhythmia.tsx, VanillaGame.tsx, tetris.tsx, and GameUI.tsx component

Implementation Details

The beat phase cycles 0→1 each beat interval. The on-beat window spans two zones to accommodate both the immediate post-beat moment and the anticipatory pre-beat moment, giving players a more forgiving hit window while maintaining visual clarity about timing.

https://claude.ai/code/session_01JaUmAPTKmyrS7w3Mn32v54

…et zones

The beat bar was broken because:
- The fill bar + CSS transition added visual lag
- The target zone (right:10%, width:15%) didn't match the actual
  on-beat window (phase > 0.75 || phase < 0.15)
- beatPhaseRef was updated via delayed useEffect sync instead of
  directly in the animation loop

Replaced the fill bar with a sweep cursor and dual target zones
that accurately reflect the hit window. Removed CSS transitions
for frame-precise positioning and added gold glow feedback when
the cursor enters the on-beat zone.

https://claude.ai/code/session_01JaUmAPTKmyrS7w3Mn32v54
@vercel
Copy link
Contributor

vercel bot commented Feb 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
azuretier.net Ready Ready Preview, Comment Feb 7, 2026 5:50pm

Request Review

React 18's automatic batching of setBeatPhase() inside
requestAnimationFrame caused dropped/delayed re-renders —
the cursor didn't move on Edge and moved inconsistently on Chrome.

Now the rAF loop sets a CSS custom property (--beat-phase) and
a data-onbeat attribute directly on the beat bar DOM element,
bypassing React reconciliation entirely. The cursor position is
driven by CSS calc(var(--beat-phase) * 100%) for frame-precise,
re-render-free animation on all browsers.

setBeatPhase is still called at ~30fps for Board's fever rainbow
effect, but it no longer drives the beat cursor.

https://claude.ai/code/session_01JaUmAPTKmyrS7w3Mn32v54
useRhythmVFX() returns a new object on every render (no useMemo).
Since vfx was in the beat timer effect's dependency array, each
React re-render restarted the timer, resetting lastBeatRef and
jumping the beat cursor back to 0. The cursor could only advance
~33ms before being reset — roughly 15% of the bar at 100 BPM.

Fix: store vfx in a stable ref (vfxRef) that's updated on every
render but doesn't trigger effect re-runs. All vfx.emit() calls
now use vfxRef.current.emit(), and vfx is removed from all
useCallback/useEffect dependency arrays.

https://claude.ai/code/session_01JaUmAPTKmyrS7w3Mn32v54
@Azuretier Azuretier merged commit 6faad76 into main Feb 7, 2026
2 checks passed
@Azuretier Azuretier deleted the claude/fix-beat-bar-NHGOZ branch February 7, 2026 17:50
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.

2 participants