Fix dice intermittently not animating on rollAll#112
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
classmutation on a die. Findings:rollDieis called for all dice on every press (even overlapping clicks), and React never overwrites the animation class mid-roll. So the recentrollCountRef/diceRefsrefactor is not dropping dice at the logic level.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-presssetState(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
rollKeyso 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 imperativedieRef+ reflow hack is removed entirely.Verification
npm run build— passesroll[1-6]class (the structural guarantee the animation restarts)https://claude.ai/code/session_01WZxB2pKeMMacz4juCo19DK
Generated by Claude Code