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

Define retargeting of animation if incoming DOM changes during a transition. #184

Open
khushalsagar opened this issue Aug 16, 2022 · 4 comments
Labels
open-spec-issue Unaddressed issue in the spec

Comments

@khushalsagar
Copy link
Collaborator

See open spec issue here.

@khushalsagar khushalsagar added the open-spec-issue Unaddressed issue in the spec label Aug 16, 2022
@flackr
Copy link

flackr commented Aug 30, 2022

Can we do something with implicit from keyframes sampling the underlying animation for smooth retargeting? E.g. https://jsbin.com/welinug/edit?js,output

@jakearchibald
Copy link
Collaborator

I still think it's reasonable to just adjust the last keyframe & element sizes, and cause a jump mid-animation.

Without a transition, there'd still be a jump - one that we encourage developers to fix, and it's part of the lighthouse score.

@vmpstr
Copy link
Collaborator

vmpstr commented Sep 6, 2022

Currently we set up an implicit css which reflects the new (incoming) state, and we set up a single "from" keyframe which has the old (outgoing) state. This means when the layout positions change, we jump mid-transition.

After some discussion, we think that we can switch this to have no implicit css, and a "from" and a "to" two keyframe animation which has both the outgoing and incoming states. Additionally, when the element's position/size change, we add a new animation to the stack (as if we called element.animate) with a single "to" keyframe which has the new incoming state. The duration of this animation is the remaining time of the previous animation in the stack. Note that we would only do this process if the base animation running on the element is the one set up from UA styles. This gives us the following properties:

  1. We smoothly retarget the position/size by default
  2. the inline css styles (width, height, and transform specifically) of the container have no bearing on the visual result of the element
  3. We properly capture duration and easing curve customization
  4. We support full animation customization, as if if the developer changed the animation name altogether then we just do whatever the developer's animation is going to do

I suspect we also eliminate a style invalidation on position/size changes, since the initial UA style is sufficient for those cases. Instead, we would rely on rAF (right before or right after) timing to update the animation by adding a new entry in the stack.

Does that all sound reasonable? Did I miss some cases?

@khushalsagar
Copy link
Collaborator Author

There has been an update to this proposal to have the stack of animations be expressed in CSS right? So we'd start with the following:

@keyframes -ua-page-transition-container-anim-foo {
  from { width: 100px; }
  to { width: 200px; }
}

::page-transition-container(foo) {
  animation-name: -ua-page-transition-container-anim-foo;
  animation-duration: 0.25s;
}

And if the element is resized to 150x150 after 125ms, then a new keyframe gets added with an updated duration:

@keyframes -ua-page-transition-container-anim-foo {
  from { width: 100px; }
  to { width: 200px; }
}

@keyframes -ua-page-transition-container-anim-foo-0 {
  to { width: 150px; }
}

::page-transition-container(foo) {
  animation-name: -ua-page-transition-container-anim-foo,-ua-page-transition-container-anim-foo-0;
  animation-duration: 0.125s;
}

I like this option because we stick with the pattern of UA animations coming from CSS which get overridden by developer styles as expected.

One downside is that animation-duration will likely be a common developer override and each time we update the animation-name, it restarts with the full duration again. Example here. Given that it'll be rare for layout to change once the transition is started, we can start with this and add a flag for the developer to opt-in to the UA overriding the duration to remaining time.

I'm also unsure what happens with easing in this case. If the easing curve is customized, does it continue with the same curve for the remaining duration or its as-if the animation restarted?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open-spec-issue Unaddressed issue in the spec
Projects
None yet
Development

No branches or pull requests

4 participants