Repository navigation
feat: pause animations in place with paused and report the frozen values with onPaused - #65
Merged
Merged
Conversation
…ues with onPaused paused freezes a view's running animations, loops included, and resumes them from the same point. onPaused reports the on-screen values of the animate keys when the pause takes effect. iOS stops the layer clock (speed 0 + timeOffset), so explicit beginTimes are now written in layer time. Android pauses animators and restarts springs from their last value and velocity. Web pauses the element's CSS transitions and animations, and restarts a loop only when its keyframes change instead of on every render. Closes #64
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
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
Closes #64.
There was no way to stop an animation where it is and continue it later.
transition: { type: 'none' }cancels and snaps to the target, so a marquee that has to freeze on touch or blur had to estimate its offset from elapsed time and remount with a newinitialAnimateto resume, which remounts (and reloads) its children.This adds two props:
paused?: boolean: freezes the view's running animations, loops included, where they are;falseresumes them from the same point. Nothing remounts.onPaused?: ({ values }) => void: fires each timepausedtakes effect, with the on-screen values of the keys set inanimate(colors asrgba()strings).Behavior worth weighing (also in the README):
EaseViews, UIKit animations) pause with it. Android and web pause only the view's own animations. After a resume that clock runs behindCACurrentMediaTime(), so a descendant that computes its ownbeginTimefromCACurrentMediaTime()starts late.animate/initialAnimateobject identities, so any re-render restarted a loop from its start; it now restarts only when the keyframes change (changing a loop'sanimatestill restarts it, paused or not). The inlinetransitionis now set in a layout effect, before the browser can compute the render's style change, so a transition always uses the current config.delaycounts from the resume.transition: { type: 'none' }and removing a property still apply immediately.onTransitionEnd: togglingpausedis a prop update, so like any re-render today it reports in-flight non-looping animations as interrupted, and their completion after the resume isn't reported.Per platform:
beginTimes for delayed and looping animations now use layer time, so animations started after a pause don't begin late.Animator.pause()/resume().SpringAnimationcan't pause, so a paused spring is cancelled and restarted from its last value and velocity, which determine the rest of its motion.getAnimations()withpause()/play(), which covers both CSS transitions and loop keyframes.getCurrentValues()from #64 is left for a follow-up.Test Plan
New example screen Loop → Pause / Resume: a marquee with Pause/Resume, the
onPausedreadout, a mount id and an image load counter, plus delayed timing, spring and enter-while-paused boxes.iOS
ios-pause-cycles.mp4
Android (emulator, three pause/resume cycles)
ease-pause-android.mp4
Web (Chrome, three pause/resume cycles)
ease-pause-web.mp4
Three pause/resume cycles per platform on the 40 pt/s marquee. Positions were tracked on every frame of the original recordings, using their real timestamps. Resume jump = where the motion after resume extrapolates back to, minus the frozen position; steady motion is 0.67 pt/frame.
screenrecord)requestAnimationFrame)There's no fixed offset, and nothing grows with the pause length. On iOS the pause frame steps back about 0.3 pt (Core Animation draws slightly ahead of
CACurrentMediaTime()), and the resume frame makes it up.onPausedmatched the measured tile edges within 0.16 pt, and nothing remounted (the mount id and image load count didn't change). A 300 ms delayed timing created while paused starts 0.32 s after resume. Timing and spring boxes paused mid-move continue at the same speed. A view mounted while paused waits at its initial values and enters on resume.onPausedmatched the screen within 0.08 dp. The paused timing and spring boxes finish at their target.onPausedmatches the computed transform, enter animations still fade, and a view mounted while paused enters on resume.