ionic-framework
ionic-framework copied to clipboard
bug: overlay animations jump forward near end in ios only
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
- [ ] v4.x
- [ ] v5.x
- [X] v6.x
- [ ] Nightly
Current Behavior
Certain animations appear to "jump forward" when completing on iOS.
This may be easier to try on an actual device, but here is a video below to illustrate:
| native | ionic |
|---|---|
Expected Behavior
I expect the animations to be smooth through the end of the animation.
Steps to Reproduce
- Open http://localhost:3333/src/components/action-sheet/test/basic?ionic:mode=ios in Safari (macOS or iOS).
- Click "Basic". Observe that the action sheet container translates in but appears to "jump forward" in the last few frames.
Code Reproduction URL
No response
Ionic Info
N/A
Additional Information
No response
This is due to a bug in WebKit, the engine that powers Safari and WKWebView: https://bugs.webkit.org/show_bug.cgi?id=241020
In the case of a Web Animation with 2 keyframes, applying the easing to the effect should produce the same visual result as applying the easing to the 0th keyframe. However, on WebKit applying the easing to the effect causes the animation to jump forward near the end.
This does not happen in Chrome or Firefox.
As a workaround, we can apply the easing to the 0th keyframe instead.
Effect easing and keyframe easing typically produce different results. Effect easing applies the easing to entire effect (over the total of n keyframes). Keyframe easing applies the easing from keyframe n to keyframe n+1.
However, in the case where there are only 2 keyframes total, the following:
square.animate([
{ offset: 0, transform: 'translateY(100vh)' },
{ offset: 1, transform: 'translateY(0vh)' }
], {
duration: 1000,
easing: 'cubic-bezier(0.32,0.72,0,1)'
});
should produce the same visual result as:
square.animate([
{ offset: 0, transform: 'translateY(100vh)', easing: 'cubic-bezier(0.32,0.72,0,1)' },
{ offset: 1, transform: 'translateY(0vh)' }
], {
duration: 1000,
});