-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Svelte 5: Transition easing functions aren't reversed during out transition #9937
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
Comments
I was wondering if this could be worked around, by creating a custom transition function which dynamically switches the easing function for a reversed one when the out transition is playing. It appears that isn't possible due to the fix in #8318 not being merged (which would allow the transition function to know the current transition direction), and also because it appears that the easing function cannot be dynamically altered, as used to be possible (which is itself a shame, since that sort of dynamic behaviour is useful). Switching the |
Yeah well, as you noticed, that's not a solution, since the animation couldn't be reversed halfway through when you have separate This seems to me like something that should be fixed by Svelte internally, there's just no possible workaround. Although the flexibility that something like a |
I was recently wondering why transitions felt weird in v5, just found out this is the culprit. I'd like to see this fixed too. |
After playing with the Web Animations API a little bit, I believe I found out a pretty straightforward way to pull this off: When the outro animation needs to be played, instead of using the native Here's a very basic demo. This achieves the desired effect: Rec.0008.mp4 |
Looking at @aradalvand 's idea, I had a go at improving the behaviour by having the first keyframe state be determined via You should be able to hammer on the Whether this sort of approach is suitable for incorporating into Svelte is another matter though (I don't know the specifics of how transitions are now implemented, other than the general move to using the animation API). |
Thanks @robertadamsonsmith, that's nice, good job. I think that's the way to go. Also, it just occurred to me that this very approach could be used to make separate Waiting for the maintainers now to tell us what they think. |
It looks like Svelte 5 is still building keyframes from the css callback returned by transition function, and since the fly function is already starting from the current style via getComputedStyle, I'm not actually sure why things are misbehaving - this seems like something that should be fixable, but I don't follow the logic in |
Thanks, I'll take a look when I'm back after the holidays :) I do wonder if this is actually a bug in Web Animations API though. I would have expected reverse to apply the easing in reverse too. I wonder if there's some configuration we're missing to make that work as expected? However if it turns out we can't use this API then we can likely do something like mentioned above, however the downside is that this won't play as smoothly when applying it to an existing transition that is active (Svelte 4 is janky with this on low end devices, Web Animations are smoother here). |
Wait, am I the only one here for who the very first video of this issue looks nothing like "Nice and graceful."? And the second one looks like "Yep, thats the correctly reversed outro". It's not perfect. But to me it's the correct outro at least for the shown intro. It's rather expectations question – "When we are specifying easing for the transition, are we expecting easing to be reversed on outro together with transition". Personally I think of an easing as an inseparable stylistic description of a transition, when transition behaves reversed it behaves reversed in its whole – with easing |
Yes. |
No, it's not. The "correct" outro involves also reversing the easing, again, that's how CSS transitions have always worked — although you could also describe the same thing as "not reversing the easing", depending on which perspective you choose to look at it, it's a bit of a semantic quibble, which is why I struggled with titling this issue properly at first, but the underlying behavior being described remains the same. Think of it this way: When you say "ease-out", for example, what you're basically saying, as the name implies, is "I want the beginning of the animation to be fast, and the ending to be slow"; the current implementation (+ The REPLs might not make this immediately obvious since they're meant to be minimal repros, but having tried this in a real-world app, I can assure you it does look very awkward (e.g. a modal that slides up and down with a highly curved easing function like |
@trueadm Any movement on this one, Dominic? |
This turned out to be super complex. I don't think we can ever get it perfectly like Svelte 4 either – as web animations just work differently. We can reverse the easing on the keyframes and re-apply them, but only once the transition has finished. Doing it during a transition and trying to reverse it causes far too many issues to be reliable. So it's better than what we have now, but is likely the best we can do with web animations – unless someone knows how we can apply custom easing separately from the keyframes. |
@trueadm What issues did this solution cause? It seemed to work perfectly reliably. |
@aradalvand It doesn't work at a core level, unfortunately. Making that change causes hundreds of unit tests to fail. |
@trueadm The fact that it causes the unit tests as they currently are to fail does not indicate that it shouldn't done though, does it? It's the unit tests that need modifying if fixing this issue makes them fail. And you didn't elaborate on what "not working at a core level" actually means, apart from it not matching the current unit tests. I'm very curious what specifically you were referring to when you said "Doing it during a transition and trying to reverse it causes far too many issues to be reliable". What are some concrete examples of those "far too many issues"? |
Svelte 5 uses the web animations API which Svelte 4 did not. There are some tricky edge cases which make them work differently/ make certain things easier but others harder. To get more details I suggest you dig into the code yourself |
@aradalvand I'm not saying this is a solved story right now. We still have work to do, however it's complicated. It turns out that replacing keyframes of a non-idle web animation in progress causes flicker between different browsers. So you can't simply just replace the keyframes with new ones with the easing reversed without there being some issues. We can reverse them once the transition has finished and the web animation is idle however, and that's what my PR did. As for why we can't just apply what was mentioned above – well that's not how transition work in Svelte. For example the What can really help me fix things is REPL cases showing the oddities in what we have right now. :) |
@dummdidumm I'm well aware of that. @robertadamsonsmith and I, however, seemed to achieve the desired result with the Web Animations API as demonstrated in the linked REPLs like this one; which is why I'm finding it surprising to hear that it somehow wasn't a feasible approach.
@trueadm Well, the only oddity left is that an outro transition that starts before the intro transition is completed now looks different in terms of easing than one that begins after the intro transition is completed. As you pointed out yourself. So, this issue has only been half-fixed right now. I build animation/transition-heavy web apps and this particular issue and this regression, so to speak, in the behavior of Svelte 5 transitions would be an absolutely massive bummer for me. I'd really want to see it fixed. |
@aradalvand The REPL I posted isn't directly applicable to how Svelte transitions work. I was relying on the browser interpolating between the current computed style and the first/last frame of the transition animation and using CSS easing, whereas Svelte transitions (such as fly) assume that the current computed style is to be maintained, and then builds a series of frames using the custom easing function, in a way that doesn't make it possible to simply resume a transition from the current style. I'd be interested to investigate the flicker issue that @trueadm mentioned though. I've not been able to reproduce any flicker after checking a few Windows and Android web browsers (with the REPL I posted). Are there specific browsers/devices that are problematic? |
@robertadamsonsmith I wasn't seeing issues with your approach above, but more with trying to apply keyframes on a non-idle transition using the @aradalvand can you link me to the other issue you mentioned? I'd like to tackle that next. |
|
Describe the bug
Take
cubicOut
as an example; in Svelte 4, this is what it looks like (see REPL):Rec.0004.mp4
Nice and graceful.
Now, in Svelte 5, however, the same exact code yields a very different "out" transition (see REPL):
Rec.0005.mp4
Which fails to reverse the easing, and thereby creates a jarring look; this is presumably because internally
Animation.reverse()
is being called for the out transition, which results in the latter type of "reversing". But this never looks good; Svelte 4's way of "reversing" the transition was the "correct" one. The Web Animations API'sreverse()
method doesn't reverse the easing, which, again, feels jarring and isn't normally what you want; so just callingreverse()
isn't sufficient on its own.There is presumably some way to simulate the former behavior using the Web Animations API, but I haven't looked into that.
It's worth noting that the former behavior is also how plain old CSS transitions (+ toggling classes) work (i.e. they also reverse the easing); so, as I said, Svelte 4 is the one doing the most natural/expected thing here. Svelte 5 should follow suit.
Reproduction
See the REPLs linked above.
Logs
No response
System Info
Severity
blocking an upgrade
The text was updated successfully, but these errors were encountered: