diff --git a/scroll-animations-1/Overview.bs b/scroll-animations-1/Overview.bs
index 6e317b50fb8..be75a8b7a53 100644
--- a/scroll-animations-1/Overview.bs
+++ b/scroll-animations-1/Overview.bs
@@ -31,6 +31,8 @@ Markup Shorthands: markdown yes
urlPrefix: https://html.spec.whatwg.org/multipage/window-object.html; type: dfn; spec: html
text: document associated with a window; url: concept-document-window
+urlPrefix: https://drafts.csswg.org/web-animations-2/; type: dfn; spec: web-animations-2
+ text: calculating an auto-aligned start time
spec:web-animations-1;
@@ -953,6 +955,11 @@ spec:selectors-4; type:dfn; text:selector
and the state of a scroll-driven animation
may be inconsistent in the composited frame.
+ When updating timeline current time,
+ the [=start time=] of any attached animation is conditionally updated.
+ For each attached animation,
+ run the procedure for [=calculating an auto-aligned start time=].
+
# Privacy Considerations # {#privacy-considerations}
There are no known privacy impacts of the features in this specification.
diff --git a/web-animations-2/Overview.bs b/web-animations-2/Overview.bs
index d78242f37d2..0fba26ee64a 100644
--- a/web-animations-2/Overview.bs
+++ b/web-animations-2/Overview.bs
@@ -138,6 +138,8 @@ urlPrefix: https://webidl.spec.whatwg.org/; type: dfn; spec: webidl
urlPrefix: http://www.ecma-international.org/ecma-262/6.0/#sec-; type: dfn; spec: ecma-262
text: code realms
text: execution contexts
+urlPrefix: https://drafts.csswg.org/scroll-animations-1/; type: dfn; spec: scroll-animations-1
+ text: html-processing-model-event-loops
@@ -288,12 +290,12 @@ follows:
:: Set |previous progress| = |previous current time| /
[=end time=]
+
1. Let |from finite timeline| be true if |old timeline| is not null and
not [=monotonically increasing timeline|monotonically increasing=].
1. Let |to finite timeline| be true if |timeline| is not null and not
[=monotonically increasing timeline|monotonically increasing=].
1. Let the timeline of animation be new timeline.
-1. Set the flag |reset current time on resume| to false.
1. Perform the steps corresponding to the first matching
condition from the following, if any:
@@ -302,38 +304,21 @@ follows:
: If |to finite timeline|,
:: 1. [=Apply any pending playback rate=] on |animation|
- 1. Let |seek time| be zero if [=playback rate=] ≥ 0, and
- |animation|'s associated effect end otherwise.
- 1. Update the animation based on the first matching condition if any:
-
-
-
- : If either of the following conditions are true:
- * |previous play state| is "running" or,
- * |previous play state| is "finished"
-
- :: Set |animation|'s [=animation/start time=] to |seek time|.
-
- : If |previous play state| is "paused":
-
- :: If |previous progress| is resolved:
-
- 1. Set the flag |reset current time on resume| to true.
- 1. Set [=animation/start time=] to unresolved.
- 1. Set [=hold time=] to |previous progress| *
- [=end time=].
-
-
- This step ensures that |previous progress| is preserved
- even in the case of a pause-pending animation with a
- resolved [=animation/start time=].
-
-
- :: Otherwise
-
- 1. Set [=animation/start time=] to |seek time|.
-
-
+ 1. set |auto align start time| to true.
+ 1. Set [=animation/start time=] to unresolved.
+ 1. Set [=animation/hold time=] to unresolved.
+ 1. If |previous play state| is "finished" or "running"
+ 1. Schedule a [=pending play task=]
+
+ 1. If |previous play state| is "paused" and
+ |previous progress| is resolved:
+ 1. Set [=hold time=] to |previous progress| * [=end time=].
+
+
+ This step ensures that |previous progress| is preserved
+ even in the case of a pause-pending animation with a
+ resolved [=animation/start time=].
+
: If |from finite timeline| and |previous progress| is resolved,
@@ -393,15 +378,38 @@ After the step to assign new effect as animation's
Waiting for the associated effect
-The definition of when an animation is ready needs to be extended to consider
-descendant effects and custom effects such that the first condition is:
+Replace:
+
+> An animation is ready at the first moment
+> where both of the following conditions are true:
+>
+> * the user agent has completed any setup required
+> to begin the playback of the animation's [=associated effect=],
+> including rendering the first frame of any [=keyframe effect=].
+>
+> * the animation is associated with a [=timeline=]
+> that is not [=inactive timeline|inactive=].
+
+With:
+> An animation is ready at the first moment
+> where all of the following conditions are true:
+>
> * the user agent has completed any setup required to begin the playback of
> each inclusive descendant of
> the animation's associated effect
> including rendering the first frame of any keyframe
> effect or executing any custom effects associated with an
> animation effect.
+>
+> * the animation is associated with a [=timeline=]
+> that is not [=inactive timeline|inactive=].
+>
+> * the animation's [=hold time=] or [=animation/start time=] is resolved.
+
+Note: an animation is not ready while it has no [=animation/start time=] or [=hold time=].
+For a [=scroll-driven animation=], the start-time is determined when [=html-processing-model-event-loop|updating the timeline=] if |auto align start time| is true.
+
Validating a CSSNumberish time
@@ -458,6 +466,8 @@ an animation, animation, to seek time is as follows:
1. If valid seek time is false, abort this procedure.
+1. Set |auto align start time| to false.
+
1. Update either animation's hold time or
[=animation/start time=] as follows:
@@ -498,8 +508,6 @@ an animation, animation, to seek time is as follows:
1. Make animation's previous current time unresolved.
-1. Set the |reset current time on resume| flag to false.
-
The procedure to set the current time of an animation,
animation, to seek time is as follows:
@@ -532,6 +540,8 @@ is as follows:
1. If valid start time is false, abort this procedure.
+1. Set |auto align start time| to false.
+
1. Let timeline time be the current time value of the
timeline that animation is associated with.
If there is no timeline associated with animation or the
@@ -551,8 +561,8 @@ is as follows:
1. Let previous current time be animation's
[=animation/current time=].
- Note: This is the [=animation/current time=] after applying the changes from the
- previous step which may cause the [=animation/current time=] to become
+ Note: This is the [=animation/current time=] after applying the changes from
+ the previous step which may cause the [=animation/current time=] to become
unresolved.
1. [=Apply any pending playback rate=] on |animation|.
@@ -560,8 +570,6 @@ is as follows:
1. Set animation's [=animation/start time=] to
new start time.
-1. Set the |reset current time on resume| flag to false.
-
1. Update animation's hold time based
on the first matching condition from the following,
@@ -600,34 +608,31 @@ as CSS Animations [[CSS-ANIMATIONS-1]].
animation has a pending pause task, and false otherwise.
1. Let has pending ready promise be a boolean flag that is
initially false.
-1. Let seek time be a time value that is initially unresolved.
1. Let has finite timeline be true if |animation| has an associated
timeline that is not
[=monotonically increasing timeline|monotonically increasing=].
1. Let previous current time be the |animation|'s
[=animation/current time=]
-1. If |reset current time on resume| is set:
-
- * Set previous current time to unresolved.
- * Set the |reset current time on resume| flag to false.
-
+1. Let enable seek be true if the auto-rewind flag is
+ true and has finite timeline is false.
+ Otherwise, initialize to false.
1. Perform the steps corresponding to the first matching
condition from the following, if any:
: If |animation|'s [=effective playback rate=] > 0,
- the auto-rewind flag is true and either
+ enable seek is true and either
animation's:
* previous current time is unresolved, or
* previous current time < zero, or
* previous current time ≥ associated effect end,
- :: Set seek time to zero.
+ :: Set the |animation|'s hold time to zero.
: If |animation|'s [=effective playback rate=] < 0,
- the auto-rewind flag is true and either
+ enable seek is true and either
animation's:
* previous current time is unresolved, or
@@ -640,31 +645,26 @@ as CSS Animations [[CSS-ANIMATIONS-1]].
:: throw an "{{InvalidStateError}}" {{DOMException}} and
abort these steps.
: Otherwise,
- :: Set seek time to |animation|'s associated effect end.
+ :: Set the |animation|'s hold time to the
+ |animation|'s associated effect end.
: If |animation|'s [=effective playback rate=] = 0 and |animation|'s
[=animation/current time=] is [=unresolved=],
- :: Set seek time to zero.
+ :: Set the |animation|'s hold time to zero.
-1. If |seek time| is resolved,
+1. If |has finite timeline| and |previous current time| is unresolved:
+ * Set the flag |auto align start time| to true.
-
-
- : If |has finite timeline| is true,
- :: 1. Set animation's [=animation/start time=] to
- seek time.
- 1. Let |animation|'s [=hold time=] be unresolved.
- 1. [=Apply any pending playback rate=] on |animation|.
-
- : Otherwise,
- :: 1. Set animation's hold time to
- seek time.
-
+ Note: If play is called for a CSS animation during style update,
+ the |animation|'s [=animation/start time=] cannot be reliably calculated until post layout since the start time is to align with the start or end of the animation range (depending on the [=playback rate=]).
+ In this case, the animation is said to have an auto-aligned start
+ time,
+ whereby the start time is automatically adjusted as needed to align the animation's progress to the animation range.
1. If animation's hold time is resolved,
let its [=animation/start time=] be unresolved.
@@ -675,10 +675,9 @@ as CSS Animations [[CSS-ANIMATIONS-1]].
1. Cancel that task.
1. Set has pending ready promise to true.
-1. If the following four conditions are all satisfied:
+1. If the following three conditions are all satisfied:
* |animation|'s [=hold time=] is [=unresolved=], and
- * |seek time| is [=unresolved=], and
* |aborted pause| is false, and
* |animation| does not have a [=pending playback rate=],
@@ -796,6 +795,34 @@ as CSS Animations [[CSS-ANIMATIONS-1]].
Issue: The procedure to [=play an animation=] needs to include scheduling a task for
updating [=custom effects=].
+Auto-aligning the start time
+
+When attached to a non-monotonic timeline, the start time of the animation may be layout dependent.
+In this case, we defer calculation of the start time until the timeline has been updated post
+layout.
+When updating timeline current time, the [=animation/start time=] of any attached animation is conditionally updated.
+The procedure for calculating an auto-aligned start time is as follows:
+
+ 1. If the |auto-align start time| flag is false, abort this procedure.
+
+ 1. If the timeline is inactive, abort this procedure.
+
+ 1. If [=play state=] is idle, abort this procedure.
+
+ 1. If [=play state=] is paused, and [=hold time=] is resolved,
+ abort this procedure.
+
+ 1. Let |start offset| be the resolved timeline time corresponding to the start of the [=animation attachment range=].
+ In the case of view timelines, it requires a calculation based on the proportion of the cover range.
+
+ 1. Let |end offset| be the resolved timeline time corresponding to the end of the [=animation attachment range=].
+ In the case of view timelines, it requires a calculation based on the proportion of the cover range.
+
+ 1. Set [=animation/start time=] to |start offset| if [=effective playback rate=] ≥ 0,
+ and |end offset| otherwise.
+
+ 1. Clear [=hold time=].
+
Pausing an animation
@@ -805,6 +832,115 @@ The procedure to [=pause an animation=] needs to refer not only to the
Likewise, the procedure to [=pause an animation=] needs to include scheduling
a task for updating [=custom effects=].
+Update the constraints for setting the seek time to only apply when using a
+monotonic timeline. A [=scroll-driven animation=] needs to defer setting the
+hold time until the animation range has been computed.
+
+Replace:
+
+> 1. Let |seek time| be
+> a [=time value=] that is initially [=unresolved=].
+> 1. Let |has finite timeline| be true
+> if |animation| has an associated [=timeline=]
+> that is not [=monotonically increasing=].
+>
+> 1. If the |animation|'s [=animation/current time=] is [=unresolved=],
+> perform the steps according to the first matching condition below:
+>
+>
+>
+> : If |animation|'s [=playback rate=] is ≥ 0,
+> ::
+> Set |seek time| to zero.
+>
+> : Otherwise,
+> ::
+>
+>
+> : If [=associated effect end=] for |animation| is positive infinity,
+> ::
+> [=throw=] an "{{InvalidStateError}}" {{DOMException}}
+> and abort these steps.
+>
+> : Otherwise,
+> ::
+> Set |seek time| to |animation|'s [=associated effect end=].
+>
+>
+>
+>
+>
+> 1. If |seek time| is [=unresolved|resolved=],
+>
+>
+>
+> : If |has finite timeline| is true,
+> ::
+> Set |animation|'s [=start time=] to |seek time|.
+>
+> : Otherwise,
+> ::
+> Set |animation|'s [=hold time=] to |seek time|.
+>
+>
+
+with:
+
+> 1. Let |has finite timeline| be true
+> if |animation| has an associated [=timeline=]
+> that is not [=monotonically increasing=].
+>
+> 1. If the |animation|'s [=animation/current time=] is [=unresolved=] and
+> |has finite timeline| is false,
+> perform the steps according to the first matching condition below:
+>
+>
+>
+> : If |animation|'s [=playback rate=] is ≥ 0,
+> ::
+> Set [=hold time=] to zero.
+>
+> : Otherwise,
+> ::
+>
+>
+> : If [=associated effect end=] for |animation| is positive infinity,
+> ::
+> [=throw=] an "{{InvalidStateError}}" {{DOMException}}
+> and abort these steps.
+>
+> : Otherwise,
+> ::
+> Set [=hold time=] to |animation|'s [=associated effect end=].
+>
+>
+>
+>
+>
+> 1. If |has finite timeline| is true,
+> and the |animation|'s [=animation/current time=] is [=unresolved=]
+> * Set the |auto align start time| flag to true.
+
+Replace:
+
+> Schedule a task to be executed at the first possible moment where both of the following conditions are true:
+>
+> * the user agent has performed any processing necessary to suspend the playback of animation’s associated effect, if any.
+>
+> * the animation is associated with a timeline that is not inactive.
+
+With:
+
+> Schedule a task to be executed at the first possible moment where all of the following conditions are true:
+>
+> * the user agent has performed any processing necessary to suspend the playback of animation’s associated effect, if any.
+>
+> * the animation is associated with a timeline that is not inactive.
+>
+> * the animation has a resolved [=hold time=] or [=animation/start time=].
+
+Note: A [=animation/start time=] is still required for a pause-pending animation if the |auto-align start time| flag is true to properly align to the animation range.
+The [=animation/start time=] is set following the procedure for [=calculating an auto-aligned start time=].
Canceling an animation
@@ -2254,18 +2390,20 @@ Update the attribute type for currentTime.
The Animation
interface
-Update the startTime and currentTime of the Animation interface as follows:
+Update the startTime and currentTime of the Animation interface, and add
+rangeStart and rangeEnd as follows:
[Exposed=Window]
partial interface Animation {
attribute CSSNumberish? startTime;
attribute CSSNumberish? currentTime;
+ attribute (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeStart;
+ attribute (TimelineRangeOffset or CSSNumericValue or CSSKeywordValue or DOMString) rangeEnd;
};
-Replace [=animation/start time=] and [=animation/current time=] attribute
-descriptions with:
+Add or update attribute descriptions as follows:
@@ -2291,6 +2429,21 @@ descriptions with:
> Setting this attribute follows the procedure to
>
set the current time of this object to the new value.
+Add:
+
+> :
rangeStart
+> :: Specifies the start of the
animation’s [=animation attachment range=].
+> Setting the attribute follows the same rules as the KeyframeAnimationOption
+>
rangeStart.
+> When reading the attribute, the returned value is either a
+> {{TimelineRangeOffset}} or the {{DOMString}} "normal".
+>
+> :
rangeEnd
+> :: Specifies the end of the
animation’s [=animation attachment range=].
+> Setting the attribute follows the same rules as the KeyframeAnimationOption
+>
rangeEnd.
+> When reading the attribute, the returned value is either a
+> {{TimelineRangeOffset}} or the {{DOMString}} "normal".
The AnimationEffect
interface