Skip to content

[BUG] Animation loop can become permanently stuck because startLoop() never reschedules when rafRef.current is stale #1014

Description

@ishubhamrathi

if (rafRef.current != null) return;

if (rafRef.current != null) return;

Component(s)

  • OptionWheel
  • LineSidebar

Possibly other components using the same animation loop pattern.

Description

Both components can stop animating because startLoop() exits early when rafRef.current is already set.

Current implementation:

const startLoop = useCallback(() => {
  if (rafRef.current != null) return;

  lastRef.current = performance.now();
  rafRef.current = requestAnimationFrame(runFrame);
}, [runFrame]);

If rafRef.current remains non-null while no animation callback is running, all future calls to startLoop() return immediately.

As a result:

  • OptionWheel never applies transforms
  • LineSidebar never updates --effect
  • Hover animations don't work
  • Selection animations don't start

Expected

Calling startLoop() should always guarantee an animation loop is running.

Actual

The component can enter a permanently idle state where rafRef.current contains an old requestAnimationFrame id but no callback executes.

Environment

  • React 18.2
  • Vite 5
  • Installed using the official shadcn CLI

Workaround

Replacing the guard with a restart fixes the issue:

if (rafRef.current != null) {
    cancelAnimationFrame(rafRef.current);
}

lastRef.current = performance.now();
rafRef.current = requestAnimationFrame(runFrame);

I verified this fixes both OptionWheel and LineSidebar.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions