This repository was archived by the owner on Jul 14, 2026. It is now read-only.
Skip spring integration on non-finite or non-positive frame durations - #2
Open
thebrowsercompany-bot2 wants to merge 35 commits into
Open
Skip spring integration on non-finite or non-positive frame durations#2thebrowsercompany-bot2 wants to merge 35 commits into
thebrowsercompany-bot2 wants to merge 35 commits into
Conversation
I was erroneously assuming that ignoring velocity was sufficient to stop upon reaching the `toValue`, however with enough velocity, the check for whether `toValue` has been reached or not is incorrect. Now, it checks to see if the delta between the current value and the value after executing the spring to see if there’s a sign change (i.e. crossing zero), meaning the `toValue` has been reached and the spring should resolve.
This adds the ability to get the destination for a `DecayAnimation`. It also allows the ability to set the destination for a `DecayAnimation` (similar to how one can with `UIScrollView`). Setting the `toValue` on a `DecayAnimation` will result in the `velocity` being adjusted so that the `DecayAnimation` will stop at the supplied `toValue`. This also adds the ability to adjust how the decay will end with regards to rounded values. Setting a value of 1.0 will result in the `DecayAnimation` always stopping on whole point values (whereas setting something like `1 / screenScale` will allow it to stop on pixel values). Implements b3ll#28
Support toValue on DecayAnimation; Add roundingFactor
…bserve Pause animation driver if necessary when unobserving animations
Introduce AnimationEnvironment to address b3ll#18
Fixed a crash on tvOS if the device’s refresh rate was set below 60fps.
A display link that restarts after screen sleep/wake can deliver a non-finite or non-positive frame duration. Feeding that into the spring solver produces non-finite state, which traps when the value is read back on the next tick. Guard against it by skipping degenerate frames.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Root Cause
On macOS,
CoreVideoDriverfeedsframe.duration(targetTimestamp - timestamp, derived fromCVTimeStamp.videoTime / videoTimeScale) straight intoSpringAnimation.tick. When the display link is torn down and restarted (e.g. after the screen sleeps and wakes), the first frame after wake can carry a non-finite or non-positive duration (a stale/zerovideoTimeScaleyieldsinf/NaN). Feeding that into the analytic spring solver produces non-finite state, which then traps when the value is read back.Fix
Guard
SpringAnimation.tickagainst non-finite and non-positive frame durations by skipping the frame. Finite durations — including large but valid ones — are unchanged, so normal playback is unaffected.Tests
Added
testSpringToleratesDegenerateFrameDuration, which ticks with zero, negative,inf, andNaNdurations and asserts the value/velocity stay finite. It fails on the pre-fix code and passes with the guard. FullMotionTestssuite passes (34 tests).This branch is
b3ll/Motion@c9a57f9(the commit currently pinned by the arc repo) plus this single fix.