Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue where Core Animation rendering engine couldn't display last frame of animation when paused #2254

Merged
merged 8 commits into from
Dec 12, 2023

Conversation

calda
Copy link
Member

@calda calda commented Dec 11, 2023

This PR fixes an issue where the Core Animation rendering engine couldn't display the last frame of the animation -- setting the animation progress to 1.0 would unexpectedly display the second-to-last frame. Fixes #2209.

Before (Core Animation) After (Core Animation) Main Thread rendering engine
Simulator Screenshot - iPhone SE (3rd generation) - 2023-12-11 at 14 27 05 Simulator Screenshot - iPhone SE (3rd generation) - 2023-12-11 at 14 26 58 Simulator Screenshot - iPhone SE (3rd generation) - 2023-12-11 at 14 27 18

We now handle this by extending the duration of the CAAnimations by one frame when the animation is paused.


Some interesting discoveries I made along the way:

When playing the animation, we don't actually display the final frame of the animation. lottie-web and both iOS rendering engines behave this way. For example, when looping the animation transitions from the second-to-last frame directly to the first frame in the next loop.

When the animation is paused, the Main Thread rendering engine always renders the last frame of the animation.

There is an interesting edge case here that I don't fully understand yet. Several animations, like LottieLogo1.json, have a totally-blank last frame. The main thread rendering engine and lottie-web handle this differently:

  • The main thread rendering engine handles this by extending the visibility of layers by one frame. This creates some bugs, like the "1" and "9/10" overlapping in the above screenshots.
  • lottie-web / lottiefiles.com appear to handle this by intelligently(?) excluding the last frame from playback. I don't understand how this works, and have asked about it here.

For now we'll have it so the Core Animation rendering engine matches the behavior of the Main Thread rendering engine.

// Anything visible during the last frame should stay visible until the absolute end of the animation.
// - This matches the behavior of the main thread rendering engine.
context.timeRemapping(outFrame) == context.animation.endFrame
? NSNumber(value: Double(1.0))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, some animations (like LottieLogo1.json) would unexpectedly render a blank frame as the last frame.

This matches the behavior of the main thread rendering engine as far as I can tell, but causes bugs. e.g. this change is why the "1" and "9/10" overlap in this screenshot:

For now let's prioritize parity with the main thread rendering engine.

Copy link
Contributor

@thedrick thedrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM @calda

@calda calda merged commit 92f70b7 into master Dec 12, 2023
16 checks passed
@calda calda deleted the cal--2209 branch December 12, 2023 00:33
cgrindel-self-hosted-renovate bot referenced this pull request in cgrindel/rules_swift_package_manager Jan 23, 2024
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [airbnb/lottie-spm](https://togithub.com/airbnb/lottie-spm) | minor |
`from: "4.3.4"` -> `from: "4.4.0"` |

---

### Release Notes

<details>
<summary>airbnb/lottie-spm (airbnb/lottie-spm)</summary>

###
[`v4.4.0`](https://togithub.com/airbnb/lottie-spm/releases/tag/4.4.0)

[Compare
Source](https://togithub.com/airbnb/lottie-spm/compare/4.3.4...4.4.0)

#### New features

- Add privacy manifest
([https://github.com/airbnb/lottie-ios/pull/2252](https://togithub.com/airbnb/lottie-ios/pull/2252))
- Codesign Lottie.xcframework
([https://github.com/airbnb/lottie-ios/pull/2259](https://togithub.com/airbnb/lottie-ios/pull/2259))
- Add time remapping support to Core Animation rendering engine
([https://github.com/airbnb/lottie-ios/pull/2286](https://togithub.com/airbnb/lottie-ios/pull/2286))
- Add official visionOS support to lottie-ios repo
([https://github.com/airbnb/lottie-ios/pull/2287](https://togithub.com/airbnb/lottie-ios/pull/2287))
- lottie-spm now supports visionOS
([https://github.com/airbnb/lottie-spm/pull/12](https://togithub.com/airbnb/lottie-spm/pull/12))
- Adopt policy on minimum supported Swift / Xcode version, update
minimum versions to Swift 5.7 / Xcode 14.1
([https://github.com/airbnb/lottie-ios/pull/2260](https://togithub.com/airbnb/lottie-ios/pull/2260))

#### Bug fixes

- Update LottieView to display placeholder using `overlay` instead of
`ZStack`
([https://github.com/airbnb/lottie-ios/pull/2289](https://togithub.com/airbnb/lottie-ios/pull/2289))
- Fix issue where Core Animation rendering engine couldn't display last
frame of animation when paused
([https://github.com/airbnb/lottie-ios/pull/2254](https://togithub.com/airbnb/lottie-ios/pull/2254))
- Do not create `DotLottieImageProvider` instance if there's no image
files
([https://github.com/airbnb/lottie-ios/pull/2271](https://togithub.com/airbnb/lottie-ios/pull/2271))
- Mark DotLottieCache as Sendable
([https://github.com/airbnb/lottie-ios/pull/2245](https://togithub.com/airbnb/lottie-ios/pull/2245))
- Fix issue where AnimationKeypath in SolidLayer could be incorrect
([https://github.com/airbnb/lottie-ios/pull/2278](https://togithub.com/airbnb/lottie-ios/pull/2278))
- Fix issue where Repeater could be displayed incorrectly
([https://github.com/airbnb/lottie-ios/pull/2276](https://togithub.com/airbnb/lottie-ios/pull/2276))
- Include dSYMs in xcframework build
([https://github.com/airbnb/lottie-ios/pull/2284](https://togithub.com/airbnb/lottie-ios/pull/2284))
- Fix parsing issue, add support for DotLottieConfiguration in SwiftUI
LottieView
([https://github.com/airbnb/lottie-ios/pull/2277](https://togithub.com/airbnb/lottie-ios/pull/2277))
- Fix issue where DotLottieImageProvider didn't handle base64 images
([https://github.com/airbnb/lottie-ios/pull/2283](https://togithub.com/airbnb/lottie-ios/pull/2283))
- Fix issue where manually interpolated keyframes could animate
incorrectly
([https://github.com/airbnb/lottie-ios/pull/2285](https://togithub.com/airbnb/lottie-ios/pull/2285))

**Full Changelog**:
airbnb/lottie-ios@4.3.4...4.4.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://togithub.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDAuMCIsInVwZGF0ZWRJblZlciI6IjM2LjEwMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: Self-hosted Renovate Bot <361546+cgrindel-self-hosted-renovate[bot]@users.noreply.github.enterprise.com>
iago849 pushed a commit to atteamapps/lottie-ios that referenced this pull request Feb 8, 2024
MoroziOS pushed a commit to MoroziOS/tmg-lottie-ios that referenced this pull request May 22, 2024
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.

Unable to reach the end of the animation when setting .currentProgress with .coreAnimation engine
2 participants