-
Notifications
You must be signed in to change notification settings - Fork 715
'effective time range' for timeRange: auto has some undesirable behaviors #4346
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
Comments
If there are no associated animations, wouldn't zero be a better default? (To match the Infinity case, and my intuition at least). I'm not sure the jumping behavior is a problem? There are plenty of other ways you can manipulate animations so that they jump? (e.g. setting the timing function, direction etc. If we could have, we would have made setting Following your suggestion, I guess we can draw a parallel with scroll anchoring. That is, if scroll position was described as a percentage and content was added to the page, the content would "jump". Indeed, this used to happen in some circumstances before browsers added scroll anchoring. So, another way to approach this would be to add time anchoring (which is what setting the playback rate currently does). You'd have to decide what circumstances trigger it, however (e.g. presumably adding an animation to the timeline would, but what about altering the duration or iteration count after adding it?). |
But changing timing properties requires modifying |
This was discussed at the Chrome/Firefox/Safari animation sync yesterday. (From memory, so excuse mistakes). We reached a general agreement that this is 'weird', but there was less consensus on whether it is bad. Brian argued that it is reasonable to expect web developers to match the duration of animations which are reusing the same ScrollTimeline. Stephen noted that with an infinite timeline if you want your animations to run for the same time, you have to set the same duration (duh) - this is arguably just the same thing for finite timelines. Brian proposed looking at how CSS might work, and that might help. The CSS syntax as written is definitely not final, but we (re)learned that you cannot share ScrollTimelines using the CSS syntax; each animation has its own. We discussed how ScrollTimelines are cheap and we should probably encourage developers to create one per Animation by providing examples to that end. There were two action items, both on smcgruer@: Action: Make the wording more accurate as to what an 'associated' animation is for a timeline. |
Investigating this. It turns out that the Web Animations spec already defines 'associated with a timeline': https://drafts.csswg.org/web-animations/#associated-with-a-timeline . Strangely, this is defined only for an Animation Effect (and refers to the undefined version for Animation) but is used for Animation! (https://drafts.csswg.org/web-animations/#ref-for-associated-with-a-timeline) So I think the steps are:
|
For Web animations, the association between an animation and a timeline is defined in prose, it's just not linkified as a definition:
However, that's the association going from animation to timeline. For the purposes of this issue it might be more clear to add a definition going the other direction or add some other definition. For example, if I have an animation associated with timeline X, but which is idle, should it be considered when calculating the time range? I suspect not and that suggests we want some other definition about the set of animations we consider. Just ones whose target effect is current or in effect for example? |
This sounds reasonable. To make sure I understand, this primarily changes the behavior to require a resolved startTime. Without an 'is current or in effect' wording, the ScrollTimeline would still consider an Animation for Assumption for the above: w3c/scroll-animations#31 is fixed, i.e. a ScrollTimeline can have an unresolved time value by scrolling outside the startScrollOffset/endScrollOffset bounds but not be considered newly inactive (and thus currentTime doesn't get held in place). There is a side-effect with using 'is current or is in effect' (or similar). When you scroll outside the range of startScrollOffset/endScrollOffset, the timeline produces unresolved time values (assuming no fill mode on the timeline). This will make all Animations which use that timeline idle, which means there will be no valid choice for Finally, I think we will need to declare a default let scrollTimeline = new ScrollTimeline({
timeRange: 'auto',
startScrollOffset: '10px',
endScrollOffset: '90px',
});
let effect1 = new KeyframeEffect(target, keyframes, { duration: 1000 });
let anim1 = new Animation(effect1, scrollTimeline);
scroller.scrollTop = 50px;
console.log(scrollTimeline.currentTime); // 500
anim1.pause();
console.log(scrollTimeline.currentTime); // 0.5 (assuming default of 1)
Returning to this, given our previous conversation I am actually partial to just leaving the behavior as is, with a spec note that reusing a ScrollTimeline is discouraged and making sure all our examples don't do that. This will cause issues if web authors do: let scrollTimeline = new ScrollTimeline({ timeRange: 'auto', ... });
let effect1 = new KeyframeEffect(target, keyframes, { duration: 1000 });
let anim1 = new Animation(effect1, scrollTimeline);
anim1.play();
setTimeout(function() {
let effect2 = new KeyfrmaeEffect(target2, keyframes2, { duration: 2000 });
let anim2 = new Animation(effect2, scrollTimeline);
anim2.play(); // anim1 will suddenly jump forward, without user input
}, 500); |
Yes, that sounds right.
The alternative, as you mention, might be to define the association as depending on having a resolved
That's an interesting test case. Yes, it's weird, but I can't think of any better option at this point.
In that example, I'm actually more concerned about what will currently happen if the author does not call |
As the spec currently stands, yes, but if we make it a requirement that the animation is current/in effect/has a resolved start time then just creating |
I started working on a PR for this today, and realized that it creates a circular dependency. Both being I don't immediately see a way around that problem (time is meant to flow from the timeline outwards, so we have to be careful about inverse dependencies). It might be the case that we have to accept that |
I thought the suggestion was to key on whether or not the |
Ah, I misunderstood you then. I will think on the implications of keying on |
I don't think keying off https://drafts.csswg.org/web-animations-1/#playing-an-animation-section, step 8.2::
This ready time is what is used to set |
I think if we manage to introduce progress-based animations as proposed in #4862 this issue will be moot. |
Progress based animations are now the course of action. The primary issue brought up here no longer applies as each animation converts its own timing into progress based timing following https://drafts.csswg.org/web-animations-2/#time-based-animation-to-a-proportional-animation |
For effective time range, the spec currently says:
There are a few questions we can ask about this.
If there are no associated animations
What is the value of the above? We have to multiply the result by
effective time range
, but that isn't specified when there are no associated animations.This could probably be fixed by just making it either 1 (so its a scroll fraction by default) or making it the scroll range (so it maps to scroll offset), but there's another issue...
When a new animation is associated with the same timeline
When the second animation is created, the ScrollTimeline's currentTime suddenly jumps and as such so would the visual output of the first animation.
The problem with timeRange: auto
The idea behind
timeRange: auto
makes a lot of sense - most of the time, you want the output of the ScrollTimeline to be linearly mapped to the possible values for whatever animation is using it. But the way it is specified falls apart in practice - under the case of multiple animations in particular.Arguably what a web developer really wants is to say "I'm using a finite timeline so I don't actually care about the duration of my effect; just make it match the timeline range". But we implemented that in a backwards manner; mutating the timeline to fit the effect duration rather than the effect duration to fit the timeline.
I don't have a specific proposal for fixing this yet; a naive approach would be to allow a special value for iteration duration which causes it to be taken from the timeline range, but this likely falls apart in the face of iteration count, etc.
The text was updated successfully, but these errors were encountered: