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

[css-animations-2] Specify the animation-trigger property #10128

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
293 changes: 292 additions & 1 deletion css-animations-2/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Editor: Brian Birtles, Invited Expert, brian@birchill.co.jp, w3cid 43194
<!-- !Issues List: <a href="https://www.w3.org/Bugs/Public/buglist.cgi?component=Animations&list_id=36653&product=CSS&query_format=advanced&resolution=---">In Bugzilla</a> -->

Abstract: This CSS module describes a way for authors to animate the values of CSS properties over time, using keyframes. The behavior of these keyframe animations can be controlled by specifying their duration, number of repeats, and repeating behavior.
Ignored Vars: auto-rewind
Ignored Vars: auto-rewind, did trigger
</pre>
<pre class=anchors>
urlPrefix: https://dom.spec.whatwg.org/; type: dfn; spec: dom
Expand All @@ -41,6 +41,7 @@ spec:web-animations-1; type:dfn;
text:active duration
text:active phase; for:animation effect
text:active time
text:active interval
text:after phase; for:animation effect
text:animation class
text:animation effect
Expand All @@ -58,7 +59,9 @@ spec:web-animations-1; type:dfn;
text:iteration count
text:iteration start
text:keyframe
text:play an animation
text:pause an animation
text:reverse an animation
text:paused play state
text:pending pause task
text:pending play task
Expand Down Expand Up @@ -690,7 +693,30 @@ The 'animation' shorthand property syntax is as follows:

<span class=prod><dfn>&lt;single-animation></dfn> = <<'animation-duration'>> || <<easing-function>> || <<'animation-delay'>> || <<single-animation-iteration-count>> || <<single-animation-direction>> || <<single-animation-fill-mode>> || <<single-animation-play-state>> || [ none | <<keyframes-name>> ] || <<single-animation-timeline>></span>

## The 'animation-trigger' property ## {#animation-trigger}
ydaniv marked this conversation as resolved.
Show resolved Hide resolved

The 'animation-trigger' property is a [=shorthand property|shorthand=]
that sets 'animation-trigger-type', 'animation-trigger-timeline',
'animation-trigger-range-start', 'animation-trigger-range-end',
'animation-trigger-exit-range-start', and 'animation-trigger-exit-range-end'
together in a single declaration,
specifying the [=animation trigger=] for an animation.

<pre class='propdef'>
Name: animation-trigger
Value: <<single-animation-trigger>>#
Initial: see individual properties
Applies to: all elements
Inherited: no
Percentages: N/A
Computed value: see individual properties
Canonical order: per grammar
Animation Type: not animatable
</pre>

<pre class=prod>
<dfn>&lt;single-animation-trigger></dfn> = <<single-animation-trigger-type>> || [ none | auto | [ [ <<dashed-ident>> | <<scroll()>> | <<view()>> ] [ normal | <<length-percentage>> | <<timeline-range-name>> <<length-percentage>>? ]{0,4} ] ]
</pre>

# Animation Events # {#events}

Expand Down Expand Up @@ -847,6 +873,271 @@ expressed in milliseconds, it must be divided by 1,000 to produce a value in
seconds before being assigned to the {{AnimationEvent/elapsedTime}} member of
the {{AnimationEvent}}.

# Animation Triggers # {#triggers}

An <dfn export>animation trigger</dfn> is used to control the playback
of its associated [=animation=] for time-driven animations.
[=Animation triggers=] follow the same [[web-animations-1#hierarchical|hierarchy]]
as animations and are associated with a [=timeline=] and an [=animation trigger effect|effect=].
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes it sound like animation triggers are separate things from animations, but I suspect we should say that as a part of updating the current time of animations we evaluate whether a trigger condition has been reached and apply a stateful change to the animation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I'll work on that


Issue: Should there be any effect of triggers on scroll-driven animations?
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect triggers on scroll-driven animations should "just work". E.g. they could play / stop the animation when the trigger condition occurs / finishes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How does each type affects a scroll-driven animation?
Furthermore, what could be the actual use-case for this? Perhaps one that I can think of now is if we have a hover-timeline in the future and we want to enable/disable it on different scroll positions. Is that what you mean?


## Animation Trigger Effects ## {#trigger-effects}
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 the internal control of how triggers work probably belongs in web-animations where we define things like how an updated time updates corresponding animations: https://drafts.csswg.org/web-animations-1/#update-animations-and-send-events

We should also be able to set up animation triggers from javascript.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, sure. We didn't discuss the WAAPI part of triggers in the issue, should I try fleshing that too in this PR? Or you're just stating this as a reason for this change?


The <dfn>animation trigger effect</dfn> applies an effect
to an [=animation=]’s playback via a mutually associated
[=animation trigger=]. This effect is defined by its [=animation trigger type|type=].

An [=animation trigger effect=] of [=animation trigger=] |trigger|
with [=animation trigger type=] |type| has an internal
<dfn export lt="animation-trigger-effect-state">state</dfn> that
can be one of the following:

<dl dfn-for=animation-trigger-effect-state dfn-type=value>
<dt><dfn>idle</dfn>
<dd>
The [=animation effect=] associated with |trigger| remains in
its [=animation effect/before phase=] and stays at zero [=animation/start time=].

<dt><dfn>primary</dfn>
<dd>
The ''primary'' effect defined by |type| is applied to its associated [=animation=].

<dt><dfn>inverse</dfn>
<dd>
The ''inverse'' effect defined by the |type| is applied to its associated [=animation=].

</dl>

Issue: Do we need a formal resolution on the spec of the idle state?

An [=animation trigger effect=] |effect| is controlled
by the [=animation attachment range|attachment range=] it is attached to,
given a flag |did trigger|, as follows:

<dl class=switch>
: If |effect|’s [=local time=] is [=unresolved=],
::
It is in its ''animation-trigger-effect-state/idle'' state, and its |did trigger| flag is set to false.

: Otherwise,
::

<dl class=switch>
: If |effect| is inside its [=active interval=],
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 defining a trigger in terms of an internal animation effect's time might be overkill. E.g. I think we could define this simply in terms of the animation timeline's time with respect to the specified range

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 struggled with that quite a bit. Eventually it worked out once I defined the same hierarchy as animations', and defined a special state for the effect. I'll try simplifying this further.

::
It is in its ''animation-trigger-effect-state/primary'' state, and its |did trigger| flag is set to true.

: Otherwise,
::

<dl class=switch>
: If |effect|’s |did trigger| flag is false,
::
It is in its ''animation-trigger-effect-state/idle'' state.

: Otherwise,
::
It is in its ''animation-trigger-effect-state/inverse'' state.

</dl>

</dl>

</dl>

## Animation Trigger Ranges ## {#trigger-ranges}

An [=animation trigger=] has at least one [=animation attachment range|range=],
its <dfn>default range</dfn>, which defines the [=active interval=] of
the [=animation trigger effect|effect=]. This range defines when
the [=animation trigger effect|effect=] is in its ''animation-trigger-effect-state/primary'' state,
as specified in [[#trigger-effects]].

An [=animation trigger=] may also have a second [=animation attachment range|range=],
the <dfn>exit range</dfn>. The [=exit range=] is used to replace [=default range=] and extend
the [=active interval=] of an [=animation trigger effect|effect=] |effect| as follows:

<dl class=switch>
: If |effect| is inside its [=active interval=],
::
It’s attached to its [=exit range=].

: Otherwise,
::
It’s attached to its [=default range=].

</dl>

Issue: Should we specify that that exit range’s edges can only be equal to or greater than the default range’s edges?

Issue: Do we need to specify the process for determining the effective attachment range in the HTML Processing Model?

## The 'animation-trigger-type' property ## {#animation-trigger-type}

The 'animation-trigger-type' property specifies the <dfn>animation trigger type</dfn>
of the [=animation trigger=]’s associated [=animation trigger effect|effect=].

<pre class='propdef'>
Name: animation-trigger-type
Value: <<single-animation-trigger-type>>#
Initial: once
Applies to: all elements
Inherited: no
Percentages: N/A
Computed value: list, each item a keyword as specified
Animation type: not animatable
Canonical order: per grammar
</pre>

<span class=prod><dfn>&lt;single-animation-trigger-type></dfn> = once | repeat | alternate | state</span>

<dl dfn-type=value dfn-for='animation trigger type'>
<dt><dfn>once</dfn>
<dd>
The ''primary'' effect is [=play an animation|triggering=] the associated animation.

<dt><dfn>repeat</dfn>
<dd>
The ''primary'' effect is [=play an animation|triggering=] the associated animation.
The ''inverse'' effect is resetting the [=animation trigger effect=]’s state back to ''animation-trigger-effect-state/idle''.

<dt><dfn>alternate</dfn>
<dd>
<dl class=switch>
: if the |did trigger| flag is false,
::
The ''primary'' effect is [=play an animation|triggering=] the associated animation.

: Otherwise,
::
The ''primary'' effect is [=reverse an animation|reversing=] the associated animation.

</dl>

The ''inverse'' effect is [=reverse an animation|reversing=] the associated animation.

<dt><dfn>state</dfn>
<dd>
The ''primary'' effect is [=play an animation|triggering or resuming=] the associated animation.
The ''inverse'' effect is [=pause an animation|pausing=] the associated animation.
</dl>

Issue: Need to bike-shed the name for type "state" type.

## The 'animation-trigger-timeline' property ## {#animation-trigger-timeline}

The 'animation-trigger-timeline' property specifies the <a>timeline</a>
of the animation’s associated [=animation trigger=].

<pre class='propdef'>
Name: animation-trigger-timeline
Value: <<single-animation-timeline>>#
Initial: auto
Applies to: all elements
Inherited: no
Percentages: N/A
Computed value: list, each item either
the keyword ''single-animation-timeline/none'',
the keyword ''single-animation-timeline/auto'',
a case-sensitive [=css identifier=],
a computed ''scroll()'' function,
or
a computed ''view()'' function
Canonical order: per grammar
Animation Type: not animatable
</pre>

Issue: Probably a trigger with timeline "none" is under-specified here. Need to clarify what it means.

## The 'animation-trigger-range' property ## {#animation-trigger-range}

The 'animation-trigger-range' property is a [=shorthand property|shorthand=]
that sets 'animation-trigger-range-start' and 'animation-trigger-range-end'
together in a single declaration,
specifying the [=animation trigger=]’s associated [=default range=].

<pre class="propdef shorthand">
Name: animation-trigger-range
Value: [ <<'animation-range-start'>> <<'animation-range-end'>>? ]#
</pre>

## The 'animation-trigger-range-start' property ## {#animation-trigger-range-start}

<pre class="propdef">
Name: animation-trigger-range-start
Value: [ normal | <<length-percentage>> | <<timeline-range-name>> <<length-percentage>>? ]#
Initial: normal
Applies to: all elements
Inherited: no
Percentages: relative to the specified [=named timeline range=] if one was specified, else to the entire timeline
Computed value: list, each item either the keyword ''animation-trigger-range-start/normal'' or a timeline range and progress percentage
Animation type: not animatable
</pre>

The 'animation-trigger-range-start' property specifies the start of the [=animation trigger=]’s
associated [=default range=].

## The 'animation-trigger-range-end' property ## {#animation-trigger-range-end}

<pre class="propdef">
Name: animation-trigger-range-end
Value: [ normal | <<length-percentage>> | <<timeline-range-name>> <<length-percentage>>? ]#
Initial: normal
Applies to: all elements
Inherited: no
Percentages: relative to the specified [=named timeline range=] if one was specified, else to the entire timeline
Computed value: list, each item either the keyword ''animation-trigger-range-end/normal'' or a timeline range and progress percentage
Animation type: not animatable
</pre>

The 'animation-trigger-range-end' property specifies the end of the [=animation trigger=]’s
associated [=default range=].

## The 'animation-trigger-exit-range' property ## {#animation-trigger-exit-range}

<pre class="propdef shorthand">
Name: animation-trigger-exit-range
Value: [ <<'animation-trigger-exit-range-start'>> <<'animation-trigger-exit-range-end'>>? ]#
</pre>

The 'animation-trigger-exit-range' property is a [=shorthand property|shorthand=]
that sets 'animation-trigger-exit-range-start' and 'animation-trigger-exit-range-end'
together in a single declaration,
specifying the [=animation trigger=]’s associated [=exit range=].

## The 'animation-trigger-exit-range-start' property ## {#animation-trigger-exit-range-start}

<pre class="propdef">
Name: animation-trigger-exit-range-start
Value: [ normal | <<length-percentage>> | <<timeline-range-name>> <<length-percentage>>? ]#
Initial: normal
Applies to: all elements
Inherited: no
Percentages: relative to the specified [=named timeline range=] if one was specified, else to the entire timeline
Computed value: list, each item either the keyword ''animation-trigger-exit-range-start/normal'' or a timeline range and progress percentage
Animation type: not animatable
</pre>

The 'animation-trigger-exit-range-start' property specifies the start of the [=animation trigger=]’s
associated [=exit range=].

## The 'animation-trigger-exit-range-end' property ## {#animation-trigger-exit-range-end}

<pre class="propdef">
Name: animation-trigger-exit-range-end
Value: [ normal | <<length-percentage>> | <<timeline-range-name>> <<length-percentage>>? ]#
Initial: normal
Applies to: all elements
Inherited: no
Percentages: relative to the specified [=named timeline range=] if one was specified, else to the entire timeline
Computed value: list, each item either the keyword ''animation-trigger-exit-range-end/normal'' or a timeline range and progress percentage
Animation type: not animatable
</pre>

The 'animation-trigger-exit-range-end' property specifies the end of the [=animation trigger=]’s
associated [=exit range=].

# DOM Interfaces # {#interface-dom}

## The CSSAnimation interface ## {#the-CSSAnimation-interface}
Expand Down