Skip to content

Commit d1335e2

Browse files
authored
[css-animationworklet] Remove multiple timelines (#890)
Drop multiple timelines and relevant concepts for Animation Worklet. This also drops the hide-bar example from spec. I may re-work this example (e.g., switching timeline via setting animation.timeline on main thread) and add it back this in future but for now dropping it is simpler. Multiple timeline was originally the solution that would allow seamless switching between between scroll timeline and regular timelines. Since then we have iterated over multiple different solutions. See #834 for a list of various design we have considered. It seems that allowing events to be handled in Animation Worklets will enable the relevant usecases. For now we drop multiple timelines fromAnimation Worklet Level-1 to ensure simplicity and better alignment with WebAnimations.
1 parent 4e41402 commit d1335e2

File tree

1 file changed

+13
-106
lines changed

1 file changed

+13
-106
lines changed

css-animationworklet/Overview.bs

+13-106
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ Animator Instance {#animator-instance-section}
379379

380380
An <dfn>animator instance</dfn> is a <a>struct</a> which describes a fully realized custom animation
381381
instance in an {{AnimationWorkletGlobalScope}}. It has a reference to an <a>animator definition</a>
382-
and owns the instance specific state such as animation effect and timelines. It consists of:
382+
and owns the instance specific state such as animation effect and timeline. It consists of:
383383

384384
- An <a>animator name</a>.
385385

@@ -392,8 +392,6 @@ and owns the instance specific state such as animation effect and timelines. It
392392

393393
- An <dfn>animator timeline</dfn> which is a <a>timeline</a>.
394394

395-
- An <dfn>animator attached timelines</dfn> which is <a>list</a> of attached <a>timelines</a>
396-
397395
- An <dfn>animator serialized options</dfn> which is a serializable object.
398396

399397
A <dfn>stateful animator instance</dfn> is an <a>animator instance</a> whose corresponding
@@ -421,26 +419,23 @@ To <dfn>create a new animator instance</dfn> given a |name|, |timeline|, |effect
421419

422420
2. Let |animatorCtor| be the <a>class constructor</a> of |definition|.
423421

424-
3. Let |timelineList| be a new <a>list</a> with |timeline| added to it.
425-
426-
4. Let |options| be <a>StructuredDeserialize</a>(|serializedOptions|).
422+
3. Let |options| be <a>StructuredDeserialize</a>(|serializedOptions|).
427423

428-
5. Let |state| be <a>StructuredDeserialize</a>(|serializedState|).
424+
4. Let |state| be <a>StructuredDeserialize</a>(|serializedState|).
429425

430-
6. Let |animatorInstance| be the result of <a>constructing</a> |animatorCtor| with
426+
5. Let |animatorInstance| be the result of <a>constructing</a> |animatorCtor| with
431427
«|options|, |state|» as arguments. If an exception is thrown, rethrow the exception and
432428
abort all these steps.
433429

434-
7. Set the following on |animatorInstance| with:
430+
6. Set the following on |animatorInstance| with:
435431
- <a>animator name</a> being |name|
436432
- <a>animation requested flag</a> being <a>frame-current</a>
437433
- <a>animator current time</a> being unresolved
438434
- <a>animator effect</a> being |effect|
439435
- <a>animator timeline</a> being |timeline|
440-
- <a>animator attached timelines</a> being |timelineList|
441436
- <a>animator serialized options</a> being |options|
442437

443-
8. Add |animatorInstance| to |workletGlobalScope|'s <a>animator instance set</a>.
438+
7. Add |animatorInstance| to |workletGlobalScope|'s <a>animator instance set</a>.
444439

445440
</div>
446441

@@ -534,6 +529,7 @@ To <dfn>migrate an animator instance</dfn> from one {{WorkletGlobalScope}} to an
534529

535530
4. If |stateful| is <b>false</b> then abort the following steps.
536531

532+
4. |stateFunction|
537533
5. Let |state| be the result of <a>Invoke</a> |stateFunction| with |instance| as the
538534
<a>callback this value</a>. If any exception is thrown, rethrow the exception and abort
539535
the following steps.
@@ -569,7 +565,7 @@ Each <a>animator instance</a> has an associated <dfn>animation requested flag</d
569565
either <dfn>frame-requested</dfn> or <dfn>frame-current</dfn>. It is initially set to
570566
<a>frame-current</a>. Different circumstances can cause the <a>animation requested flag</a> to be
571567
set to <a>frame-requested</a>. These include the following:
572-
- Changes in the <a>current time</a> of any <a>timeline</a> in the animator's <a>animator attached timelines</a>
568+
- Changes in the <a>current time</a> of the animator's <a>timeline</a>
573569
- Changes in the <a>current time</a> of the animator's corresponding <a>Worklet Animation</a>
574570

575571
[[#running-animators]] resets the <a>animation requested flag</a> on animators to
@@ -765,13 +761,12 @@ When the procedure to <a>set the timeline of an animation</a> for a given |workl
765761
is called, then <a>set animator instance of worklet animation</a> given |workletAnimation|.
766762

767763

768-
Timeline Attachment {#timeline-attachment}
769-
-------------------
770-
771-
Issue(810): Define semantics of attachment and detachment.
772764

773765
ScrollTimeline {#scroll-timeline}
774766
---------------------------------
767+
<em>This section is not normative.</em>
768+
769+
775770
{{ScrollTimeline}} is a new concept being proposed for addition to web animation API. It defines
776771
an animation timeline whose time value depends on the scroll position of a scroll container.
777772
<a>Worklet animations</a> can have a scroll timeline and thus drive their scripted effects based
@@ -848,96 +843,8 @@ There are no known privacy issues introduced by these features.
848843
Examples {#examples}
849844
====================
850845

851-
Example 1: Hidey Bar. {#example-1}
852-
-----------------------------------------
853-
An example of header effect where a header is moved with scroll and as soon as finger is lifted it
854-
animates fully to close or open position depending on its current position.
855-
856-
<xmp class='lang-markup'>
857-
858-
<div id='scrollingContainer'>
859-
<div id='header'>Some header</div>
860-
<div>content</div>
861-
</div>
862-
863-
<script>
864-
await CSS.animationWorklet.addModule('hidey-bar-animator.js');
865-
const scrollTimeline = new ScrollTimeline({
866-
scrollSource: $scrollingContainer,
867-
orientation: 'block',
868-
timeRange: 1000
869-
});
870-
const documentTimeline = document.timeline;
871-
872-
// Note we pass in two timelines in the options bag which allows the animation to read their
873-
// currenTime values directly.
874-
const animation = new WorkletAnimation(
875-
'hidey-bar',
876-
new KeyframeEffect($header,
877-
[{transform: 'translateX(100px)'}, {transform: 'translateX(0px)'}],
878-
{duration: 1000, iterations: 1, fill: 'both' }]),
879-
scrollTimeline,
880-
{scrollTimeline, documentTimeline});
881-
882-
animation.play();
883-
</script>
884-
</xmp>
885-
886-
<xmp class='lang-javascript'>
887-
888-
// Inside AnimationWorkletGlobalScope
889-
890-
registerAnimator('hidey-bar', class HidybarAnimator extends StatefulAnimator {
891-
constructor(options, state) {
892-
this.scrollTimeline_ = options.scrollTimeline;
893-
this.documentTimeline_ = options.documentTimeline;
894-
895-
if (state) {
896-
this.startTime_ = state.startTime;
897-
this.direction_ = state.direction;
898-
}
899-
}
900-
901-
animate(currentTime, effect) {
902-
const scroll = this.scrollTimeline_.currentTime; // [0, 100]
903-
const time = this.documentTimeline_.currentTime;
904-
905-
const activelyScrolling = this.scrollTimeline_.phase == 'active';
906-
907-
let localTime;
908-
if (activelyScrolling) {
909-
this.startTime_ = undefined;
910-
localTime = scroll;
911-
} else {
912-
this.startTime_ = this.startTime_ || time;
913-
// Decide on close/open direction depending on how far we have scrolled the header
914-
// This can even do more sophisticated animation curve by computing the scroll velocity and
915-
// using it.
916-
this.direction_ = scroll >= 50 ? +1 : -1;
917-
localTime = this.direction_ * (time - this.startTime_);
918-
}
919-
920-
// Drive the output effect by setting its local time.
921-
effect.localTime = localTime;
922-
}
923-
924-
getter state() {
925-
return {
926-
startTime: this.startTime_,
927-
direction: this.direction_
928-
}
929-
}
930-
});
931-
932-
</xmp>
933-
934-
Issue: This example uses a hypothetical "phase" property on timeline as a way to detect when user
935-
is no longer actively scrolling. This is a reasonable thing to have on scroll timeline. A simple
936-
fallback can emulate this by detecting when timeline time (i.e. scroll offset) has not changed in
937-
the last few frames.
938-
939846

940-
Example 2: Twitter header. {#example-2}
847+
Example 1: Twitter header. {#example-1}
941848
--------------------------
942849
An example of twitter profile header effect where two elements (avatar, and header) are updated in
943850
sync with scroll offset.
@@ -997,7 +904,7 @@ function clamp(value, min, max) {
997904

998905
</xmp>
999906

1000-
Example 3: Parallax backgrounds. {#example-3}
907+
Example 2: Parallax backgrounds. {#example-2}
1001908
-----------------------------------------
1002909
A simple parallax background example.
1003910

0 commit comments

Comments
 (0)