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

Inconsistent animation speed depending on monitor refresh rate #387

Closed
1 task done
Tracked by #321
macjuul opened this issue Oct 22, 2022 · 29 comments · Fixed by #459
Closed
1 task done
Tracked by #321

Inconsistent animation speed depending on monitor refresh rate #387

macjuul opened this issue Oct 22, 2022 · 29 comments · Fixed by #459
Labels
bug Something isn't working resolved This issue is resolved

Comments

@macjuul
Copy link

macjuul commented Oct 22, 2022

Bug is related to

  • embla-carousel (core package)

Embla Carousel version

  • v7.0.3

Describe the bug

  • The animation speed when navigating via controls or using scrollTo is affected by the refresh rate of your monitor. In my case, carousels will animate more than twice as fast on 144hz monitors compared to 60hz monitors, causing it to either feel to slow or too fast.

CodeSandbox

  • Not applicable, this can be tested by manually limiting the refresh rate of your browser on the Embla examples page.

Steps to reproduce

  1. View a carousel normally (either with 60Hz or higher)
  2. Limit your browser framerate to 30Hz or lower (You can do this in Firefox by setting layout.frame_rate to 30 in about:config)
  3. View the same carousel again, you will notice slide animations being twice as slow

Expected behavior

  • It is expected that the time it takes for the carousel to travel one snap point is not dependent on the monitors refresh rate as this can cause unintended side effects. I'm using Embla to create a slide animation between multiple forms in a stepper, and to some people the animation feels too slow, while for others it's fine.

Additional context

  • This issue is caused by requestAnimationFrame attempting to sync to the monitors refresh rate. This should be fixable by using the time value passed into the callback by requestAnimationFrame (Here's an explanation on StackOverflow)

Thank you for your great library!

@macjuul macjuul added the bug Something isn't working label Oct 22, 2022
@davidjerleke
Copy link
Owner

davidjerleke commented Oct 23, 2022

Hi @macjuul,

Yep, I actually already have this on my to do so thank you for creating this issue 👍🏻. I’ll let you know when I have something.

Best,
David

@robksawyer
Copy link

robksawyer commented Jan 26, 2023

Anyway we could add the ability to adjust the ease type? Using different easings with the autoplay plugin would be a win!

Update: I realized all I needed to do is adjust the timing on the container via css. I'm using tailwind and adding the following class to the inner container div made things much smoother.

.ease-out-quad {
    transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

@macjuul
Copy link
Author

macjuul commented Mar 26, 2023

Hey @davidjerleke, have you had any time to look into this yet? or perhaps an estimate on when this could be tackled?

Thanks!

@davidjerleke
Copy link
Owner

Hi @macjuul,

Thanks for the follow up. I can’t give proper time estimates because I’m the sole dev on this project with a huge to do list, and I’m maintaining this on my spare time which means a little bit here and there.

But what I can say is that I have it planned for the 7.2.1 release:

  • 7.2.0 (to be released soon, currently working on this)
  • 7.2.1 <— I have planned it for this release

Best,
David

@macjuul
Copy link
Author

macjuul commented Mar 26, 2023

Great to hear @davidjerleke! Thanks for the heads up, looking forward to a fix. Take your time, no need to hurry 🙂

This was referenced Mar 30, 2023
@davidjerleke
Copy link
Owner

@macjuul, just wanted to let you know that I will start working on this issue the next time I work on this project. Can’t give an ETA though but I will start looking into it.

@davidjerleke
Copy link
Owner

Hi @macjuul,

If you want to help out and speed up the process, you could test this CodeSandbox on:

  • On a 60 Hz device.
  • On a 120 Hz device.

The total runtime for the animation on each device should be something around 1500 milliseconds (give and take 30 milliseconds), no matter the refresh rate.

If that's the case, I have a good starting point and will continue implementing this feature into the Embla Carousel core. Also note that the runtime won't be exactly 1500 and may slightly vary from one try to another (about 30 milliseconds give and take).

Thanks in advance.
David

@macjuul
Copy link
Author

macjuul commented Apr 5, 2023

Hi @macjuul,

If you want to help out and speed up the process, you could test this CodeSandbox on:

  • On a 60 Hz device.
  • On a 120 Hz device.

The total runtime for the animation on each device should be something around 1500 milliseconds (give and take 30 milliseconds), no matter the refresh rate.

If that's the case, I have a good starting point and will continue implementing this feature into the Embla Carousel core. Also note that the runtime won't be exactly 1500 and may slightly vary from one try to another (about 30 milliseconds give and take).

Thanks in advance. David

This is indeed working perfectly on 144hz, 60hz, and 30hz. Good job!

@davidjerleke
Copy link
Owner

@macjuul, thanks for taking time and testing it out 👍. I'll let you know when I have a working frame rate agnostic Embla draft.

@davidjerleke davidjerleke added the investigating Issue is being looked into label Apr 11, 2023
@davidjerleke davidjerleke added upcoming A feature or bug fix is on its way for this issue and removed investigating Issue is being looked into labels Apr 20, 2023
@davidjerleke
Copy link
Owner

davidjerleke commented Apr 22, 2023

Hi @macjuul and anyone tracking this issue. I’m done implementing this feature and it will be released with v8.0.0-rc01 pretty soon. I just have to update some examples on the documentation website. Stay tuned.

Best,
David

@davidjerleke davidjerleke linked a pull request Apr 22, 2023 that will close this issue
davidjerleke added a commit that referenced this issue Apr 22, 2023
@davidjerleke davidjerleke added resolved This issue is resolved and removed upcoming A feature or bug fix is on its way for this issue labels Apr 22, 2023
@davidjerleke
Copy link
Owner

davidjerleke commented Apr 22, 2023

To be released with v8.0.0-rc01.

@davidjerleke
Copy link
Owner

@macjuul this feature has been released with v8.0.0-rc01.

@bugproof
Copy link

bugproof commented Sep 29, 2024

This library feels extremely slow for some reason on iOS 120 Hz still
Transitions feel like 60hz

@davidjerleke
Copy link
Owner

This library feels extremely slow for some reason on iOS 120 Hz still
Transitions feel like 60hz

@bugproof it's hard to know what you mean with extremely slow because it's highly subjective, but the whole point with refresh rate agnostic animations, is that the animation duration should be the same regardless of monitor refresh rate. Otherwise the duration option would be highly unpredictable:

  • 60hz default speed
  • 120hz twice as fast
  • 240hz four times as fast

Instead it should be (like it's designed now):

  • 60hz default speed
  • 120hz same speed as 60hz
  • 240hz same speed as 60hz

You can easily test the speed with this code:

let startTime = 0

emblaApi.on('settle', () => {
  const nowTime = new Date().getTime()
  const diffTime = nowTime - startTime

  console.log(`Transition took ${diffTime}ms`)
})

function scrollNextWithTimer() {
  startTime = new Date().getTime()
  emblaApi.scrollNext()
}

scrollNextWithTimer()

When you try that on monitors with different refresh rates, the animation should take approximately the same time, with an acceptable diff of 1-50 ms (because of how requestAnimationFrame works).

@bugproof
Copy link

bugproof commented Sep 30, 2024

@davidjerleke the animation is not fluid on iOS browsers - it doesn't seem like 120hz. I compared it across few different libraries.

https://blaze-slider.dev/ (has it's own issues and unmaintained but animations are very fluid)
https://github.com/beynar/svelte-light-carousel (also very fluid, probably the best one I've found in terms of animation smoothness, but also unmaintained)

Those libs also use requestAnimationFrame so I have no idea what code in embla-carousel is responsible for this

If you use or ever used airbnb, they also have carousel component on mobile in reviews section, now compare embla-carousel to that on iOS and you will see what I mean.

I didn't test how it looks on android devices.

Instead it should be (like it's designed now):

60hz default speed
120hz same speed as 60hz
240hz same speed as 60hz

So to my understanding it is locked to 60hz and doesn't take advantage of high refresh rate screens

@davidjerleke
Copy link
Owner

davidjerleke commented Sep 30, 2024

@bugproof where did you test this? The examples page? And what do you mean by not fluid? Does it stutter?

@bugproof
Copy link

bugproof commented Sep 30, 2024

@bugproof where did you test this? The examples page? And what do you mean by not fluid? Does it stutter?

Not sure how to describe it. It's not stuttering. It's like using 60hz display instead of the 120hz one. I tested it on both examples page and my own project. Maybe I can record it but I don't know if recording will capture it.

@davidjerleke
Copy link
Owner

davidjerleke commented Sep 30, 2024

@bugproof please help me understand you better by being more precise with your words. Example:

Smooth or fluid animations: In my world, this means that the animation is continuous/fluid from point A to B, doesn’t stutter and isn’t choppy, regardless of the animation speed. Be it a slow or fast animation.

So based on that definition, is it stuttering? Or is the animation still smooth/fluid, but you think it feels like the animation is taking too long on a 120hz screen?

@bugproof
Copy link

bugproof commented Sep 30, 2024

@bugproof please help me understand you better by being more precise with your words. Example:

Smooth or fluid animations: In my world, this means that the animation is continuous/fluid from point A to B, doesn’t stutter and isn’t choppy, regardless of the animation speed. Be it a slow or fast animation.

So based on that definition, is it stuttering? Or is the animation still smooth/fluid, but you think it feels like the animation is taking too long on a 120hz screen?

Then by your definition it's choppy/stuttering. It't not about animation speed but the way it runs on 120hz.

Or is the animation still smooth/fluid, but you think it feels like the animation is taking too long on a 120hz screen?

I don't think so I tried playing with duration but it didn't help. You can easily compare other carousels if you own iOS device. In my case I was testing it on a brave browser.

@davidjerleke
Copy link
Owner

davidjerleke commented Oct 1, 2024

@bugproof could you provide a screen recording?

And which Apple device are you using? Please share both hardware and software versions.

Additionally, please answer my previous question about where you’re testing? Is it the examples page on the website?

@bugproof
Copy link

bugproof commented Oct 2, 2024

I use iPhone 13 pro. On the screen recording it's not visible as the recording has a fixed frame rate. I would need to record the physical screen with some other phone perhaps.

Yes I tested in the examples page you've linked.

@davidjerleke
Copy link
Owner

@bugproof would you mind testing this sandbox on both 120hz and 60hz and let me know if you experience the same problem in that sandbox?

@bugproof
Copy link

bugproof commented Oct 6, 2024

@bugproof would you mind testing this sandbox on both 120hz and 60hz and let me know if you experience the same problem in that sandbox?

Yes the same problem in that sandbox. The animation looks like it's skipping some frames and it's visible to the naked eye. On 60hz it's even worse but I almost never use 60hz anymore so I can't tell.

@davidjerleke
Copy link
Owner

@bugproof thanks. I’ll look into it when I get the chance. It’s a bug in that case.

@bugproof
Copy link

bugproof commented Oct 6, 2024

Also both blaze slider and the other slider I have tried don't have this issue. The sliding animation there is buttery smooth almost like it was a native iOS app.

@davidjerleke
Copy link
Owner

@bugproof I know what the problem is. I don’t have access to 120hz screens so that’s why I couldn’t test this. But you’ve helped me narrow down the bug.

@davidjerleke
Copy link
Owner

@bugproof would you mind helping out one more time and try this CodeSandbox to see if the animation is smooth on your 120hz devices?

@bugproof
Copy link

@bugproof would you mind helping out one more time and try this CodeSandbox to see if the animation is smooth on your 120hz devices?

Just tried it. Works slightly better I think? Still not as silky smooth as other libs from my list.

@davidjerleke
Copy link
Owner

davidjerleke commented Oct 23, 2024

@macjuul or anyone else with a refresh rate higher than 60Hz. Please test the CodeSandbox and see if the animation is smooth or choppy, and let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working resolved This issue is resolved
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants