Skip to content

LB-1965 : smooth progress bar animation with drag-to-seek#3664

Open
Gopal7387 wants to merge 11 commits intometabrainz:masterfrom
Gopal7387:LB-1965-drag-to-seek
Open

LB-1965 : smooth progress bar animation with drag-to-seek#3664
Gopal7387 wants to merge 11 commits intometabrainz:masterfrom
Gopal7387:LB-1965-drag-to-seek

Conversation

@Gopal7387
Copy link
Copy Markdown
Contributor

Problem

The BrainzPlayer progress bar had some problems. LB-1965

It had two issues.

The first issue with the BrainzPlayer progress bar was that the playback animation did not move smoothly. Also BrainzPlayer progress bar animation was controlled by React state updates that happened every 300 milliseconds, which made the BrainzPlayer progress bar jump in steps of moving smoothly.
The second issue with the BrainzPlayer progress bar was that you could not drag the BrainzPlayer progress bar to change the position of the playback.
You could only click on a position, on the BrainzPlayer progress bar to change the playback position.

Solution

Replaced the React state-driven width% approach with a
requestAnimationFrame loop that writes transform: scaleX() directly
to the DOM via a ref. This gives true 60fps animation with zero React
re-renders per frame.

Added a circular scrubber handle that appears on hover and follows the
playhead. Users can now click and drag anywhere on the bar to seek.

What changed

ProgressBar.tsx

  • rAF loop reads performance.now() - updateTime to interpolate live
    playhead position between atom updates
  • progressBarInnerRef receives direct scaleX writes — no setState
    in the animation path
  • Added isDraggingRef, rectCacheRef, pendingSeekMsRef to coordinate
    drag state without touching React
  • Document-level pointermove / pointerup listeners so drag works
    even if mouse leaves the bar
  • pendingSeekMsRef holds the optimistic position after seek fires,
    preventing the bar from snapping back while the player catches up
  • Keyboard ArrowLeft/Right seek also goes through pendingSeekMsRef
    for the same snap-free behaviour
  • cursor: grabbing on document.body during active drag

brainzplayer.scss

  • Added width: 100% to .progress-bar (required for scaleX base)
  • Added overflow: visible to .progress to unclip the handle
  • Added .dragging rule to pin bar height during drag
  • Added .progress-handle styles (14px circle, $primary-color,
    hover-only via scaleX transition)
  • Removed legacy border-right nubbin — the handle replaces it

Testing

Tested locally with a YouTube-backed track:

  • Bar animates smoothly at 60fps during playback
  • Handle appears on hover, disappears on mouse leave
  • Drag works across the full bar width, including when mouse
    leaves the element
  • No snap-back after releasing drag
  • Keyboard seek (ArrowLeft/Right) works correctly
  • .music-player fullscreen view unaffected

Notes

Handle color and hover-only behaviour confirmed with @Aerozol . No new colours introduced.

AI usage:
If you did use AI:
[ ] I used AI tools for communication
[ ] I used AI tools for coding
[ ] I understand all the changes made in this PR

Screen.Recording.2026-04-02.at.1.02.40.AM.1.1.mov

@Gopal7387 Gopal7387 changed the title LB-1965 drag to seek handle LB-1965 : smooth progress bar animation with drag-to-seek Apr 1, 2026
@Gopal7387
Copy link
Copy Markdown
Contributor Author

Gopal7387 commented Apr 11, 2026

Hi @anshg1214
Please take a look at this, when you get a moment.
🙂

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