- From: Olga Gerchikov via GitHub <sysbot+gh@w3.org>
- Date: Mon, 23 Dec 2019 19:48:44 +0000
- To: public-css-archive@w3.org
# Proposal for Spec Changes Based on Discussion on 2019-12-18
## Scroll Timeline - Dropping Fill Mode
1. https://drafts.csswg.org/scroll-animations-1/#dom-scrolltimeline-fill - remove fill attribute.
1. https://drafts.csswg.org/scroll-animations-1/#current-time-algorithm - update ScrollTimeline.currentTime calculation as follows:
- If current scroll offset is less than startScrollOffset, return (0 - epsilon) or -infinity.
- If current scroll offset is greater than or equal to endScrollOffset, return ( effective time range + epsilon) or +infinity.
- Consider: do we need explicitly address a case when startScrollOffset equals to endScrollOffset?
1. https://drafts.csswg.org/web-animations-1/#animationtimeline - add timeline state readonly attribute: TimelineState {Inactive, BeforeStart, InRange, AfterEnd}
Timeline State | Document Timeline | Scroll Timeline | Null Timeline | Animation Behavior
------------ | ------------- | ------------ | ------------- | -------------
Inactive | https://drafts.csswg.org/web-animations-1/#document-timelines: Prior to establishing the time origin for its associated document, a document timeline is inactive. A document timeline that is associated with a Document which is not an active document is also considered to be inactive. | If `scrollSource `is null, does not currently have a CSS layout box, or if its layout box is not a scroll container, return an unresolved time value. | always | ‘Paused’ animations - no change. Other animations become idle unless animation.currentTime is set.
BeforeStart | never | If current scroll offset is less than `startScrollOffset `| never | Backwards filling animations fill backwards, other show no effect.
InRange | Always when the timeline is active. | If current scroll offset is greater than or equal to `startScrollOffset` and less than `endScrollOffset`. | never | Playing normally
AfterEnd | never | If current scroll offset is greater than or equal to `endScrollOffset `| never | Forwards filling animations fill forwards, other show no effect. | Forwards filling animations fill forwards, other show no effect.
## Web Animations Spec Changes
For the purpose of this discussion null timeline is handled the same as inactive timeline.
1. https://drafts.csswg.org/web-animations/#responding-to-a-newly-inactive-timeline - drop this section. Instead clarify animation state when responding to inactive timeline as follows:
- Start time is preserved.
- Hold time is unresolved.
- Play state is ‘idle’.
1. Add a section “Responding to a newly active timeline”:
- If hold_time is resolved, calculate start_time based on the hold_time and timeline current time.
1. https://drafts.csswg.org/web-animations/#playing-an-animation-section - update to handle inactive timelines as follows:
- If the timeline is inactive and both animation start and current time are unresolved, set start time to zero (or timeline.getInitialCurrentTime())
1. https://drafts.csswg.org/web-animations/#pausing-an-animation-section - update to handle inactive timelines. Differentiate between states:
- Start and hold time are unresolved, play state is ‘idle’ (animation.play was not called).
- Start time is resolved, hold time is unresolved, play state is ‘idle’ (play was called).
- Start and hold time are resolved, play stay is ‘paused’ (play was called, timeline became inactive, animation.currentTime was set)
1. https://drafts.csswg.org/web-animations/#setting-the-current-time-of-an-animation - drop #3:
- If animation has no associated timeline or the associated timeline is inactive, make animation’s start time unresolved.
- This preserves the invariant that when we don’t have an active timeline it is only possible to set either the start time or the animation’s current time.
1. https://drafts.csswg.org/web-animations/#play-states
1. Include the following condition into the “paused” state definition:
- If both start and hold time are resolved and timeline is inactive (or null).
1. Include the following condition into the “idle” state definition:
- The current time of animation is unresolved, the timeline is inactive and has pending play state.
## Use Cases
1. An animation that is idle until its timeline starts to play
```javascript
scroller.style.overflow="none";
scroll_timeline = new ScrollTimeline({scrollSource: scroller, ...});
animation = new Animation(new KeyframeEffect(...}], { duration: 2000}), scroll_timeline);
animation.play();
console.log(animation.startTime); // 0
console.log(animation.currentTime); // null
console.log(animation.playState); // idle
```
1. An animation that is filling backwards until its timeline starts to play.
- Same as bullet 1.
1. Likewise for the above at the other end of the timeline.
- _Is it playback rate < 0? If so exactly as bullet 1._
1. Set the initial playback position of an animation so that when its timeline starts to play, it picks up from that point.
```javascript
scroller.style.overflow="none";
scroll_timeline = new ScrollTimeline({scrollSource: scroller, ...});
animation = new Animation(new KeyframeEffect(...}], { duration: 2000}), scroll_timeline);
animation.currentTime = 100;
animation.play();
console.log(animation.startTime); // 0
console.log(animation.currentTime); // 100
console.log(animation.playState); // paused
// make the timeline active
scroller.style.overflow="scroll";
console.log(animation.startTime); // 0
console.log(animation.currentTime); // 100
console.log(animation.playState); // running
```
1. Hot-swapping timelines (switch from scroll-based to time-based).
```javascript
scroller.style.overflow="scroll";
scroll_timeline = new ScrollTimeline({scrollSource: scroller, ...});
animation = new Animation(new KeyframeEffect(...}], { duration: 2000}), scroll_timeline);
animation.play();
...
scroller.scrollTop = '50px';
...
console.log(animation.startTime); // 0
console.log(animation.currentTime); // 500 or some other number
console.log(animation.playState); // running
animation.timeline = document.timeline;
console.log(animation.startTime); // 0
console.log(animation.currentTime); // some number based on the new timeline.currentTime
console.log(animation.playState); // running or finished
```
1. Timeline becomes newly inactive while the animation is playing.
```javascript
scroller.style.overflow="scroll";
scroll_timeline = new ScrollTimeline({scrollSource: scroller, ...});
animation = new Animation(new KeyframeEffect(...}], { duration: 2000}), scroll_timeline);
animation.play();
...
scroller.scrollTop = '50px';
...
console.log(animation.startTime); // 0
console.log(animation.currentTime); // 500 or some other number
console.log(animation.playState); // running
// Make the timeline inactive
scroller.style.overflow="none";
console.log(animation.startTime); // 0
console.log(animation.currentTime); // null
console.log(animation.playState); // idle
```
1. Seek an animation that is not attached to an active timeline and get meaningful values out of it.
```javascript
// Continuation of the above
scroller.style.overflow="none";
console.log(animation.startTime); // 0
console.log(animation.currentTime); // null
console.log(animation.playState); // idle
animation.currentTime = 1000;
console.log(animation.startTime); // 0
console.log(animation.currentTime); // 1000
console.log(animation.playState); // paused
```
1. Cont. bullet 7 - the timeline becomes active.
```javascript
scroller.style.overflow="scroll";
console.log(animation.startTime); // some number calculated from the current time of 1000.
console.log(animation.currentTime); // 1000
console.log(animation.playState); // running
```
--
GitHub Notification of comment by ogerchikov
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/2066#issuecomment-568565738 using your GitHub account
Received on Monday, 23 December 2019 19:48:46 UTC