Need help debugging animations

I had a brilliant idea for implementing an animated responsive tab bar component, but I need help debugging animations. Explanation The idea is as follows: instead of making the indicator reside in the tab bar element, move it inside the currently active tab. This way if the tab changes its width the indicator will resize as well. To animate it, we need to calculate offsets (left and right) of the previous tab relative to the current tab. If there are multiple ongoing animations we need to readjust each single one (create a new animation relative to the current tab and set its currentTime to the time of the animation we are adjusting). The problem If I have 2 simulatenous animations, everything works as expected, but with 3 or more the indicator starts shifting. (see attachment) I'm not that good at doing maths in coordinate space, so I must have miscalculated something. I hope someone can point me in the right direction. Minimal, reproducible example To observe the problem, quickly click through 3 or more different tabs (the animation will break) Here's the link to a MRE (heavily simplified): https://codesandbox.io/p/devbox/tab-bar-36kj36
23 Replies
Brendonovich
Brendonovich•4mo ago
My advice would be to just use Kobalte's tabs which can handle the animation for you 😅 https://kobalte.dev/docs/core/components/tabs
deminearchiver
deminearchiverOP•4mo ago
It breaks...
deminearchiver
deminearchiverOP•4mo ago
deminearchiver
deminearchiverOP•4mo ago
I haven't seen a perfect tabs implementation yet
Brendonovich
Brendonovich•4mo ago
i'm probably gonna fix that at some point, it's a problem in my app too but at least i don't have to write animation code lol
Brendonovich
Brendonovich•4mo ago
will be fixed soon, go ahead and use it https://github.com/kobaltedev/kobalte/pull/458
GitHub
Recalculate tab indicator styles on resize by Brendonovich · Pull R...
The tab indicator currently doesn't resize if the tab trigger changes size. Adding a resize observer on the selected tab seems to be an easy fix.


Screen.Recording.2024-08...
deminearchiver
deminearchiverOP•4mo ago
That's nice But resize observer seems like a big performance issue
Brendonovich
Brendonovich•4mo ago
do you know a better way?
deminearchiver
deminearchiverOP•4mo ago
That's what I was trying to achieve ¯\_(ツ)_/¯ My way only has some calculations which are only done whenever tab index changes
Brendonovich
Brendonovich•4mo ago
wouldn't yours need a resize observer too for if the tab size changes? kobalte's implemention pretty much only runs the calculations when the selected tab element changes too
deminearchiver
deminearchiverOP•4mo ago
No In my case the indicator is inside the active tab element so left: 0 and right: 0 provide auto resize In my case it can be resized even while animating
Brendonovich
Brendonovich•4mo ago
are you basically reparenting the indicator when the animation finishes?
deminearchiver
deminearchiverOP•4mo ago
When it starts*
Brendonovich
Brendonovich•4mo ago
Is that compatible with css transitions?
deminearchiver
deminearchiverOP•4mo ago
I think it's not, but I'm not making an unstyled component also WAAPI is hardware accelerated as well
Brendonovich
Brendonovich•4mo ago
Yeah if you’re not using css transitions that’s fair
deminearchiver
deminearchiverOP•4mo ago
I just realized I also wanted to make the indicator to have this stretching effect so I have to rewrite all of that logic to have separate animations for left and right edges https://firebasestorage.googleapis.com/v0/b/design-spec/o/projects%2Fm3%2Fimages%2Flasu1iqx-3P%20-%20Behavior-%20Fixed%20tabs%20Hero.mp4?alt=media&token=51db9a01-3477-4b3a-9224-09400eaea124
deminearchiver
deminearchiverOP•4mo ago
Also WAAPI is compatible with controlled animations (e.g dragging the content area could control the indicator animation)
deluksic
deluksic•4mo ago
I like your idea. I tried implementing it a bit simpler here https://playground.solidjs.com/anonymous/0633f857-6c75-432b-aa8c-e167155fb7f4
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
deluksic
deluksic•4mo ago
This example makes the duration depend on sqrt(distance) traveled https://playground.solidjs.com/anonymous/51f8765f-cc7c-4e28-a820-4fbfdb589918
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
deminearchiver
deminearchiverOP•4mo ago
That's nice! Though I would consider not using CSS variables and sqrt since it has pour support
deluksic
deluksic•4mo ago
CSS props should be supported since 2016? Not sure about sqrt, but you can do it in js easily
deminearchiver
deminearchiverOP•4mo ago
I mean, css props can have name conflicts
Want results from more Discord servers?
Add your server