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

Add queue for animation when visualEl is deferred #2293

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

gurkerl83
Copy link

@gurkerl83 gurkerl83 commented Aug 11, 2023

What's changed?
This pull request introduces changes to the animationControls function to handle scenarios where the visualElement might not immediately subscribe, especially in the context of the LazyMotion component.

Introduced Start Queue: An array that temporarily holds animation start calls. This ensures animations are deferred until their respective visual elements have subscribed to the animation controller.

Flush Mechanism: Once a visualElement subscribes, any queued animations are immediately processed and played.

Error Handling: Added robust error handling to cater to potential issues during the animation process. This ensures promises are either resolved upon successful completion or rejected in case of errors.

Benefits:
This change ensures animations are consistently played in scenarios involving delayed visualElement subscriptions, enhancing user experience and ensuring predictable behavior.

How to test:

Integrate the LazyMotion component, described in #2292

  • Integrate the LazyMotion component into a project.
  • Import features dynamically to keep bundle size small.
  • Use m-Components.
  • Call controls.start() before the visualElement has subscribed - in the effect.

Ensure that animations play consistently, irrespective of when the controls.start() is called in relation to the visualElement subscription.

Fixes #2292

What's changed?
This pull request introduces changes to the animationControls function to handle scenarios where the visualElement might not immediately subscribe, especially in the context of the LazyMotion component.

Introduced Start Queue: An array that temporarily holds animation start calls. This ensures animations are deferred until their respective visual elements have subscribed to the animation controller.

Flush Mechanism: Once a visualElement subscribes, any queued animations are immediately processed and played.

Error Handling: Added robust error handling to cater to potential issues during the animation process. This ensures promises are either resolved upon successful completion or rejected in case of errors.

Benefits:
This change ensures animations are consistently played in scenarios involving delayed visualElement subscriptions, enhancing user experience and ensuring predictable behavior.

How to test:

Integrate the LazyMotion component, described in framer#2292

- Integrate the LazyMotion component into a project.
- Import features dynamically to keep bundle size small.
- Use m-Components.
- Call controls.start() before the visualElement has subscribed - in the effect.

Ensure that animations play consistently, irrespective of when the controls.start() is called in relation to the visualElement subscription.
@mattgperry
Copy link
Collaborator

We actually used to have something like this in AnimationControls for when people in Framer would call .start() inside the render function body.

My concern with this, it might work ok in instances where the features are expected to arrive shortly after we trigger the animations but conceivably they could load a long time after animations are triggered at which point, are the animations still relevant? Would it be better to instantly finish animations until this? I'm not sure.

@gurkerl83
Copy link
Author

gurkerl83 commented Aug 30, 2023

@mattgperry

This is what you mentioned, right fc2dda0

The key difference from the previous implementation, see the commit mentioned and the current PR, is that framer-motion subscribe triggers the start of queued animations, not a react lifecycle hook.

New implementation

  1. Animation control "start" adds pending animations to the queue if no subscribers are registered yet
  2. Pending animations get started when the function "subscribe" executes. When framer motion has prepared the respective visualElement (meaning also lazy feature loading is finished) - the animation feature - triggers the subscribe call; "pending" animations get started.

Difference to the previous behavior

  1. Animation control "start" adds pending animations to the queue, but if not yet mounted. Note: The current PR implementation looks for a reaction of framer-motion as described above, not an outside (React dependence)
  2. Mount starts pending animations. This did not guarantee that visualElement is complete and that the lazy feature loading has been completed. This is because the mount gets called from a react side effect, which does not know anything about the status of visualElement and framer-motion internals.

About your questions
Would it be better to instantly finish animations until this?
I am not sure if I understand correctly, but the visualElement is not there yet, and the same goes for the animation feature, which triggers subscribe.

So my answer might be:
Animations have not even started because subscribe has never fired.

Are the animations still relevant?
I think so because, for the same reason as above, animations are not executed yet; you can not skip the animation and go directly to the end state of an animation right?

Thx!

@gurkerl83
Copy link
Author

@mattgperry Maybe you can find a bit of time to think about the provided concept again? Would be awesome if this or something similar could land somehow. Thx!

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.

Delayed visualElement subscription can miss animations in using LazyMotion
2 participants