Skip to content

Fix dice intermittently not animating on rollAll#112

Merged
AdamTyler merged 1 commit into
masterfrom
claude/fix-rollall-animation-restart
Jun 23, 2026
Merged

Fix dice intermittently not animating on rollAll#112
AdamTyler merged 1 commit into
masterfrom
claude/fix-rollall-animation-restart

Conversation

@AdamTyler

Copy link
Copy Markdown
Owner

Summary

Fixes the bug where, on repeated/rapid Roll All presses, random dice would not animate (appear to "skip" the roll) even though the totals still completed.

Root cause

I reproduced the demo's exact wiring in jsdom and traced every class mutation on a die. Findings:

  • rollDie is called for all dice on every press (even overlapping clicks), and React never overwrites the animation class mid-roll. So the recent rollCountRef/diceRefs refactor is not dropping dice at the logic level.
  • The weak point is the CSS animation restart: the roll was started imperatively with el.className = 'die'void el.offsetWidth (force reflow) → el.classList.add('roll' + n). That restart trick is unreliable, and the recent refactor removed a per-press setState (setRollCount) that previously forced a React commit each press — so rapid presses can now skip the style flush the restart depended on, intermittently failing to replay the animation.

Fix

Drive the roll through React state and bump a rollKey so the animated element remounts on every roll. A freshly mounted node always plays its CSS keyframe animation, so the restart is now deterministic and independent of commit timing. The imperative dieRef + reflow hack is removed entirely.

Verification

  • npm run build — passes
  • jsdom harness across full-wait, fast-overlapping (30ms), and near-completion press sequences: on every press all dice remount and carry a roll[1-6] class (the structural guarantee the animation restarts)
  • ⚠️ Not yet visually confirmed in a real browser (no Chromium available in CI here). Kept as a draft — please deploy the demo and confirm the dice no longer skip on repeated Roll All presses.

https://claude.ai/code/session_01WZxB2pKeMMacz4juCo19DK


Generated by Claude Code

The roll animation was triggered imperatively by resetting the die's
className and forcing a reflow (className='die' + offsetWidth + classList.add).
This restart is unreliable when React's commit timing shifts, so on rapid /
overlapping rollAll presses some dice would not restart their animation and
appeared to skip rolling (while totals still completed).

Drive the roll through React state instead and bump a rollKey so the animated
element remounts on every roll, which restarts the CSS keyframe animation
deterministically. Removes the dieRef/reflow hack entirely.

Verified in jsdom: across full-wait, fast-overlapping, and near-completion
press sequences, all dice remount and receive a roll class on every press.
Needs visual confirmation on the demo in a real browser.

https://claude.ai/code/session_01WZxB2pKeMMacz4juCo19DK
@AdamTyler AdamTyler marked this pull request as ready for review June 22, 2026 20:28
@AdamTyler AdamTyler merged commit d791f8c into master Jun 23, 2026
1 check passed
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