Start the declared animation from the initial styles - #640
Conversation
A lone target value tells Motion to animate from wherever the element is now, so a settled animation had nothing left to move on the next play() — replaying meant repeating the starting state in the animate keyframes as [from, to] arrays. Motion now folds each initial style into the keyframes as that property's starting point, so the start is declared once and the declared animation replays identically. MotionSequence composes its segments from the same keyframes. An explicit array still wins, and a property initial says nothing about still animates from the current state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVXrJ8idMfvt667yJadvB8
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feature/motion-examples-feedback #640 +/- ##
======================================================================
+ Coverage 87.75% 87.77% +0.01%
Complexity 145 145
======================================================================
Files 153 153
Lines 5415 5422 +7
Branches 1030 1031 +1
======================================================================
+ Hits 4752 4759 +7
Misses 579 579
Partials 84 84
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Code ReviewRisk: Low — The change is safe to merge and implements the declared animation replay behavior without identified blocking issues. Updates Review usage: 58,696 in (48,849 cached) / 1,160 out tokens — $0.0121 (openrouter/openai/gpt-5.6-luna, thinking: low) Reviewed by @weareikko/code-review v0.9.5 for commit 6272684. |
What
Declaring a replayable animation used to mean writing the starting state twice:
<!-- before: initial repeated inside the keyframes --> data-option-initial='{ "opacity": 0, "y": 24 }' data-option-animate='{ "opacity": [0, 1], "y": [24, 0] }'because a lone target value tells Motion to animate from wherever the element is now — so once the animation had settled, the next
play()moved nothing (a real bug, caught driving the doc previews in a browser: the replay button did nothing).Motionnow folds eachinitialstyle into the keyframes as that property's starting point, so the start is declared once:<!-- after --> data-option-initial='{ "opacity": 0, "y": 24 }' data-option-animate='{ "opacity": 1, "y": 0 }'MotionSequencecomposes its segments from the samekeyframesgetter, so a whole choreography replays identically.[from, to]array is never overridden, and a propertyinitialsays nothing about still animates from the current state — the one-off-transition case.initialandanimateoption docs describe the composition.Test plan
initial+ single value →[from, to]), arrays and initial-less properties left alone, and the same fold inside aMotionSequencesegment.🤖 Generated with Claude Code
https://claude.ai/code/session_01FVXrJ8idMfvt667yJadvB8