Skip to content

Conversation

@kevers-google
Copy link
Contributor

[web-animations-2] Add hold phase to an animation (issue #4325)

This PR is an update on #5479, which converts the PR to a delta spec change. The PR introduces addtional factors when calculating the phase of an animation effect. When using a monotonic timeline, the boundaries for the before and after phase can be determined based on the start delay, end time and active duration. The phase of a scroll timeline linked animation needs to factor in scroll offsets. This requirement is achieved by introducing the "current phase" of an animation, which in turn depends on the hold phase when the animation is paused.


: Otherwise,
:: The <a>current phase</a> is the [=timeline phase=] of the associated
<a>timeline</a>.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this need the current phase algorithm from animation effect? I.e. before if the local time is less than before-active boundary time, after if it's after, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The animation effect handles that calculation, this is just the phase that gets passed to the animation effect to help it with its calculation. It is basically passing through the timeline phase, but adjusting for if the animation is paused.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consolidated by moving the logic to the effect phase calculation. I think originally this was a bit confusing since when the timeline phase = active case, we still need to determine if the effect phase is before, active or after. So timeline/animation phase is not the same as effect phase. Having said that, I think the benefit of encapsulating hold phase is not worth the potential for confusing in introducing "animation phase".

> animation effect's <a>local time</a> is not <a>unresolved</a> and
> <em>any</em> of the following conditions are met:
>
> 1. the <a>local time</a> is less than the <a>before-active boundary time</a>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local time of an animation effect defers to the associated animation anyways, I think we should probably do something similar to what web-animations-1 does for local time where we refer the phase calculation to the associated animation. I would link it but https://drafts.csswg.org/web-animations-1/ seems to be broken :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I originally wrote it this way to avoid the animation reaching into the effect to get timing information. It should work either way though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the logic based on removing the need for "animation phase". Please let me know what you think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should note that this PR is not ready to land as it builds on top of CSSNumerish current/start times, which should land first. Preliminary push to address the comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR should be ready for (re)review now.

[=hold time=] be |current time to match|.
1. If |animation|'s [=playback rate=] is zero, let
|animation|'s [=hold time=] be |current time to match| and
let [=hold phase=] be the |animation|'s [=current phase=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be the timeline's phase. The current phase of the animation that we are telling to play is not well defined and ultimately the only phase that needs to be held is the timeline phase AFAICT.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, oversight when removing animation current phase.

:: 1. Set <var>animation</var>'s <a>hold time</a> to
<var>seek time</var>.
1. Set <var>animation</var>'s <a>hold phase</a> to
[=timeline active phase|active=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand why an unresolved seek time should result in an animation in the active phase. Shouldn't we unset the hold phase so that we fall back to calculating the animation phase to be idle?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent error right after the abort step. It looks like the error got introduced by the PR that fixed indent as it is also in the main branch and I didn't catch it when adding the hold phase rules. If seek time is unresolved we abort in step 1.2.

complete the pause operation by performing the following steps:
1. Set <var>animation</var>'s <a>hold time</a> to <var>seek time</var>.
1. Set <var>animation</var>'s <a>hold phase</a> to
[=timeline active phase|active=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hold phase calculation in this PR overrides (comes before) the normal animation phase calculation, so I think this will result in an incorrect phase if you pause an animation at a time before / after the active time.

Copy link
Contributor Author

@kevers-google kevers-google Sep 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think overrides is the wrong term here since hold phase and effect phase are different things. The effect phase depends on timeline phase and local time. By setting a hold phase when the animation is paused, we are locking down the timeline phase at the time the animation was paused. Since local time will also be locked down via hold time, we should get a consistent result for the effect change.

The hold phase is being set a bit naively here. If offsets are not 0% and 100%, then we could be in the before or after phase.

The problem is a bit tricky to solve in all cases since the pending pause could be triggered before the scroll timeline time has synced to the scroll position (new scroll timeline). We would not pick up the timeline phase until the next animation update cycle. Perhaps it is OK to leave the hold phase as inactive for this particular edge case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think overrides was the correct term before your most recent update to calculating the effect phase. The very first rule was that if the hold phase was phase X, effect phase is phase X, and the other rules for determining before/after phase only applied if the hold phase was unset. So effectively if the hold phase was set, the effect phase would match the hold phase. I think with your recent update this has been resolved so that the active hold phase allows the effect phase to still be before / after.

> 1. <a>animation</a>'s <a>hold phase</a> is unresolved, <em>and</em>,
> <a>animation</a>'s [=timeline phase=] is [=timeline/before phase|before=],
> <em>or</em>
> 1. <a>animation</a>'s <a>hold phase</a> is unresolved, <em>and</em>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these conditions that the hold phase is unresolved may be causing a lot of issues where you set the hold phase to active which results in the animation phase being unable to resolve to before or after even if the local time is before / after the active duration.

Copy link
Contributor Author

@kevers-google kevers-google Sep 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this last condition should we updated to include hold phase active.

This will imply that the timeline's effective start and end offsets are hard limits on the active region even with negative delays. It'll still be possible for the timeline phase to be active and the effect phase to be before/after (with the fix for hold phase being active).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a definition for "effective timeline phase" to simplify and correct the logic.

> <em>and</em> <em>either</em> of the following conditions are met:
> 1. the <a>local time</a> is less than the <a>before-active boundary
> time</a>, <em>or</em>
> 1. [=timeline duration=] is unresolved, the <a>animation direction</a> is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this now require the timeline duration to be unresolved? This seems like it has overlap with #6673 and we should resolve this separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can pull this out into a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulling it out to a separate PR.

complete the pause operation by performing the following steps:
1. Set <var>animation</var>'s <a>hold time</a> to <var>seek time</var>.
1. Set <var>animation</var>'s <a>hold phase</a> to
[=timeline active phase|active=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think overrides was the correct term before your most recent update to calculating the effect phase. The very first rule was that if the hold phase was phase X, effect phase is phase X, and the other rules for determining before/after phase only applied if the hold phase was unset. So effectively if the hold phase was set, the effect phase would match the hold phase. I think with your recent update this has been resolved so that the active hold phase allows the effect phase to still be before / after.


> In addition to the <a>hold time</a>, an <a>animation</a> maintains a
> <dfn>hold phase</dfn> which is set along with the <a>hold time</a> to
> determine the <a>current phase</a> of an <a>animation</a> with a fixed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be helpful to explain add that the hold phase is used to hold the effective timeline phase.

e.g. how about instead of "to determine the current phase of an animation with a fixed current time", use
"to hold the effective timeline phase of an animation with a fixed current time"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

:: 1. Set <var>animation</var>'s <a>hold time</a> to
<var>seek time</var>.
1. Set <var>animation</var>'s <a>hold phase</a> to
[=timeline phase=].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think the animation has a definition for timeline phase so you probably need to say the associated timeline's [=timeline phase=] (here and elsewhere)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


<dl class="switch">

:: 1. Set <var>animation</var>'s <a>hold time</a> to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these extra statements should be here, maybe this was a merge conflict? If we need additional steps they should go in either of the switch conditions for if |has finite timeline|. I think all switches should be immediately followed by a condition optionally containing a list of steps to follow if that condition matches.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the merge conflict.

@flackr flackr merged commit 2424c01 into w3c:main Sep 30, 2021
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.

3 participants