-
Notifications
You must be signed in to change notification settings - Fork 658
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
[scroll-animations] Support progress-based animations on finite timelines #4862
Comments
It may make the automatic range a little less magical when timeRange is unspecified if the default timeRange was 100%. Then the animation could assume 100% (by whatever means we represent that internally) as the duration. |
Taking this to its logical conclusion, maybe animations without durations do not actually have a visible local time (from the developer point of view). We could add progress which would return the position within the animation. |
Yeah, there's an interesting circular dependency here between It does feel like a pretty drastic change to the model, however. In terms of the API, I wonder if we could make the You'd still have the problem of what time scale to use, but maybe something arbitrary like 1000 would provide sufficient resolution? 100 might be even better since is represents a percentage better but might not give enough resolution. I suspect this is worth thinking about in relationship to group effects, however. I can imagine very similar cases for group effects -- e.g. wanting to specify the duration on the group effect and then define child effects as having an offset within that (e.g. start delay of 50% and duration of 25%, or a combination of both -- start delay of 50% and duration of 1s). We should also check that, whatever solution we arrive at, it's not too hard to swap out a |
I think it touches a lot of surfaces but it doesn't have to change much of the internals.
Yes, exactly! For ease of implementation, we can convert to a time value internally.
We could convert whatever internal time scale we use back to a percentage for the user-facing API's. This would allow us to have a better resolution internally without having to actually change all time values to something else. It might make sense to have a precision requirement on progress-bound animations which could be used as guidance by implementers to choose their internal representation. We might want to use a different unit type when returning values such that time values and percentages don't get mistaken for each other - i.e. return '20%' instead of 20.0 or 0.2 or expose them as different properties (i.e. let anim = element.animate(
{opacity: [0, 1]},
{delay: '20%',
duration: 5000}
);
anim.effect.updateTiming({duration: 10000}); // delay is scaled appropriately
Agreed. I think it makes perfect sense to allow using progress anywhere a time can be used with the caveat that we'd need to either throw or scale to 0 / Infinity for infinite duration animations.
I think that for the cases where this makes sense it won't be too hard. If your animation duration is a percentage, then switching to a So concretely I think it makes sense to try to sort out the answers to the broad questions, and then we can work up a proposal and find the rough edges / gaps. At a high level
[1] Presumably the length of a ScrollTimeline is also not a time but instead a percentage (of the total scroll distance or just '100%'?) |
This is a personal view but for I also think it's self descriptive and intuitive in a way that integers aren't: mix(origin, target, 0.5)
// vs
mix(origin, target, 50) |
Late to the party (as always) but happy this conversation is happening. I personally think this issue is primordial to a successful specification of I really like the general idea of being able to specify a relative value for delay and duration, this will indeed be very useful for time containers. |
I did some thinking about this proposal and time-keyed Keyframe effect(#4907) one and their implications. Here I will try to share some of my understanding so far in form of a proposal and explore some more interesting edge cases. Hopefully this will be useful in our F2F discussion to help tease out some Graphviz Dot filedigraph D { label = "Current model"; labelloc = "t";TL [ AN [ KFE [ TL -> AN [label=" time" fontcolor=grey] } TL;DRBelow are some changes to the web animation model and API that I think will achieves both these usecases. In the new model the animation continues to produce a progress value while it can receive either progress or time from its timeline. Also the keyframes may be keyed by time values but they continue to consume only progress. Later I discuss some of the edge cases associated with these changed. Summary of proposed changes:
Additional DetailSidenote: I use the term progress (e.g., a value in [0, 1]) when referring to progress of animation/timeline and percentage (value in 0% 100%) when referring to a fraction of a whole (which could be time or progress). Dealing with conflicting modesWhen we allow both progress-based and time-based timelines and animations then some combinations of these may not be valid. See the table below:
So here are the invalid situation in this model with some suggested reasonable behavior for them:
Open Questions:
Using progress/percentage in the APIOnce we have a progress-based timeline, it obviates the need for specifying animation timings in terms of time but we can simply have them be declared in terms of progress as well. Another alternative is to accept percentages which can be either mapped to time or progress making animation timing relative which is especially nice once we have group effects. I think here are the main questions:
The introduction of a new set of properties seems to increase the API surface and make writing generic animation code less ergonomic as devs need to check the animation type and use the right property. Another consideration is that if we overload the same properties then for input properties we need to have different JS types (e.g., string and double) for percentage/progress and time values so that parsing logic can differentiate them. Also for some output properties reading them from Animation API and using them again with the same API to create a new animation should ideally preserve the semantic. The latter case does not matter for computed output attributes (e.g., Animation.currentTime) Note that there is some precedent to consider here:
Having said these I suggest this approach: Accept timing input (duration, delay,...) as unit less percentages ( duration: '80%') and time (duration: 800). This allows us to differentiate between them based on type. The fact that percentages are unit less means that in future we can resolve them against other time values and they are not limited to representing progress. (If we go with this idea, perhaps we should allow use of percentage for specifying offsets.) Output computed timing values as double which may be progress or time depending on the animation/timeline mode. This is consistent with existing API that has both except that we now overload the same property. I think this is simple and lends itself to doing math and computation using computed values. TODO: look into CSSOM Types to see if we should use those instead? Below is an example of how the above proposal would look like in practice. // Lets create a progress-based animation with a progress-based timeline (scroll timeline)
Const t = new ScrollTimeline()
const a = $div.animate({opacity: 0}, {duration: '80%', delay: '20%', timeline: t};
// The conversion scheme allows the same to work if I use time values for duration
const b = $div.animate({opacity: 0}, {duration: 800 , delay: 200, timeline: t};
document.scrollingElement.scrollTop = 100; // assume this scrolls the page half-way.
// Scroll timeline is progress-based
a.timeline.currentTime; // 0.5
// A is a progress based animation so we return <progress>
a.currentTime; // 0.5
a.effect.getComputedTiming().localTime; // 0.5
// Progress is one case where we have already use progress
a.effect.getComputedTiming().progress; // 0.375
// B is a time-based animation so we match that and output accordingly
b.currentTime; // 500
b.effect.getComputedTiming().localTime; // 500
b.effect.getComputedTiming().progress; // 0.375
// What about input values? We maintain the format for them which means they can be reused for another animation without losing their semantic.
a.effect.getTiming().duration; // "80%"
b.effect.getTiming().duration; // 800 Assigning time-based animations to a progress-based timelineThis is an interesting edge case. What happens when we associate a time-based animation with a finite duration to a progress based timeline. It will be reasonable if this case works as expected. To enable this we need a mapping between progress values to time values. Here is a simple proposal that archives this:
This process ensures that the relationship between delay/duration/endDelay is preserved and they have the intended effect. Note that each animation has its own specific _TimeToProgressRatio _so associating another animation to the same timeline does not affect any other animations. So let’s consider a bit more complex case where there is a time-keyed keyframes involved. Here we first resolve auto/unspecified values against children. In this case we resolve the auto value to 100ms. So the animation end is 150ms which gives us a 0.66 time to percent ratio. Figure 3. A more complicated scenario involving auto duration and time to progress mapping.Putting it all together:
What about GroupEffects (TODO/Defer)There was a suggestion that once we support progress/percentages for timings, we can perhaps use the same for group effects. I think this can work nicely if we use percentages for input timing properties. For example consider having a child effect duration/delay be specified in percentages.
TODO: Things get more complicated if we mix both of these and create inter-dependencies. This needs more consideration. Mixing time/progress values in a single Animation (TODO/Defer)It is not clear to me at this point how or if at all this should work. |
Thank you for all the time you put into this. I really appreciate it. I mostly agree but was imaging a slightly different approach, although perhaps it is really just different phrasing.
Nit: We might be saying the same thing but I'm getting confused because animations don't produce progress.
Nit: Likewise here, animations don't have a duration or delay, effects do. Similarly, animations don't convert current time into simple progress, effects do. But possibly we're still thinking the same thing. The approach I had in mind is maybe a little more bottom-up however. Something like:
Notes:
|
I've updated the pull request to clarify the key points from our discussion. In particular
I believe this allows developers to use auto duration for now (in fact requires it for scroll timeline since anything else results in a 0 duration animation), and should not conflict with future specifications of how percentage based durations could work as auto is implementing the "filling" behavior that makes sense for unspecified values. We may want to specify automatic filling behavior if the animation's iteration duration is not auto so that switching a time-based animation to a scroll timeline does the "right thing", let me know. |
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Implemented ScrollTimeline timeRange "auto" Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Implemented ScrollTimeline timeRange "auto" Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1097041 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Implemented ScrollTimeline timeRange "auto" Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1097041 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Implemented ScrollTimeline timeRange "auto" Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1097041 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Implemented ScrollTimeline timeRange "auto" Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Implemented ScrollTimeline timeRange "auto" Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor <[email protected]> Reviewed-by: Robert Flack <[email protected]> Cr-Commit-Position: refs/heads/master@{#826533}
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor <[email protected]> Reviewed-by: Robert Flack <[email protected]> Cr-Commit-Position: refs/heads/master@{#826533}
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor <[email protected]> Reviewed-by: Robert Flack <[email protected]> Cr-Commit-Position: refs/heads/master@{#826533}
… ScrollTimelines, a=testonly Automatic update from web-platform-tests Initial implementation of progress based ScrollTimelines This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor <[email protected]> Reviewed-by: Robert Flack <[email protected]> Cr-Commit-Position: refs/heads/master@{#826533} -- wpt-commits: d494b8ec23759c6bfb747bee1ff3a1b3d67f5177 wpt-pr: 26142
… ScrollTimelines, a=testonly Automatic update from web-platform-tests Initial implementation of progress based ScrollTimelines This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor <[email protected]> Reviewed-by: Robert Flack <[email protected]> Cr-Commit-Position: refs/heads/master@{#826533} -- wpt-commits: d494b8ec23759c6bfb747bee1ff3a1b3d67f5177 wpt-pr: 26142
…timing. r=birtles `sTiming` is a hack and I believe animation-delay, animation-iteration-count, animation-direction, and animation-fill-mode should be meaningful for scroll-linked animations. (I will add the tentative wpt in Bug 1775327.) So we need to introduce a normalized timing when resolving the specified timing. Also, this patch makes the bug of printing scroll animations detectable. No behavior is changed and I'd like to remove the magic values and do normalization in Bug 1775327. Note: Based on w3c/csswg-drafts#4862 and web-animations-2, we will introudce CSSNumberish for duration, current time, and delay. That is, we will accept percentage for animation-duration, animation-delay. However, Gecko doesn't support CSSNumberish for those values, so we'd like to normalize these time values in Bug 1775327. This patch is the 1st step: split the normalized timing from the specified timing, and use it when resolving the timing, for progress-based timeline. Differential Revision: https://phabricator.services.mozilla.com/D149683
…timing. r=birtles `sTiming` is a hack and I believe animation-delay, animation-iteration-count, animation-direction, and animation-fill-mode should be meaningful for scroll-linked animations. (I will add the tentative wpt in Bug 1775327.) So we need to introduce a normalized timing when resolving the specified timing. Also, this patch makes the bug of printing scroll animations detectable. No behavior is changed and I'd like to remove the magic values and do normalization in Bug 1775327. Note: Based on w3c/csswg-drafts#4862 and web-animations-2, we will introudce CSSNumberish for duration, current time, and delay. That is, we will accept percentage for animation-duration, animation-delay. However, Gecko doesn't support CSSNumberish for those values, so we'd like to normalize these time values in Bug 1775327. This patch is the 1st step: split the normalized timing from the specified timing, and use it when resolving the timing, for progress-based timeline. Differential Revision: https://phabricator.services.mozilla.com/D149683
…fox-animation-reviewers,birtles This implements the normalization of the specified time, defined in [web-animations-2]: https://drafts.csswg.org/web-animations-2/#normalize-specified-timing. However, it is possible to update this, based on the spec issue: w3c/csswg-drafts#4862. For now, we just do normalization for delay, end delay, and iteration duration based on the end time. And make sure the end time is equal to the timeline duration. Differential Revision: https://phabricator.services.mozilla.com/D149685
…fox-animation-reviewers,birtles This implements the normalization of the specified time, defined in [web-animations-2]: https://drafts.csswg.org/web-animations-2/#normalize-specified-timing. However, it is possible to update this, based on the spec issue: w3c/csswg-drafts#4862. For now, we just do normalization for delay, end delay, and iteration duration based on the end time. And make sure the end time is equal to the timeline duration. Differential Revision: https://phabricator.services.mozilla.com/D149685
This implements the normalization of the specified time, defined in [web-animations-2]: https://drafts.csswg.org/web-animations-2/#normalize-specified-timing. However, it is possible to update this, based on the spec issue: w3c/csswg-drafts#4862. For now, we just do normalization for delay, end delay, and iteration duration based on the end time. And make sure the end time is equal to the timeline duration. Differential Revision: https://phabricator.services.mozilla.com/D149685 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1775327 gecko-commit: 71bbfaecf629a3d73c72600d35c0ac2965516d60 gecko-reviewers: firefox-animation-reviewers, birtles
This implements the normalization of the specified time, defined in [web-animations-2]: https://drafts.csswg.org/web-animations-2/#normalize-specified-timing. However, it is possible to update this, based on the spec issue: w3c/csswg-drafts#4862. For now, we just do normalization for delay, end delay, and iteration duration based on the end time. And make sure the end time is equal to the timeline duration. Differential Revision: https://phabricator.services.mozilla.com/D149685 bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1775327 gecko-commit: 71bbfaecf629a3d73c72600d35c0ac2965516d60 gecko-reviewers: firefox-animation-reviewers, birtles
I believe all of the necessary changes to allow progress-based animations has landed in the spec. Closing this issue. |
This work is the first step in implementing upcoming spec change in: w3c/csswg-drafts#4862 Converted AnimationTimeline::currentTime() to CSSNumberish Added AnimationTimeline::duration Bug: 1140602 Change-Id: I5c9b8b7130b91faae5f172493ba5f55d77b4bdd6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2476900 Commit-Queue: Jordan Taylor <[email protected]> Reviewed-by: Robert Flack <[email protected]> Cr-Commit-Position: refs/heads/master@{#826533} GitOrigin-RevId: 65b2df47e0b1001a4f113f2ec323509bd27b77ca
Problem
Currently, when you write an animation based on a ScrollTimeline, you have to provide an arbitrary animation duration, e.g.:
By default, ScrollTimeline's
auto
value for effective scroll range will assume the range of the animation. This means that whatever duration is supplied, scroling from (in this case) 0px to 200px will advance the animation from 0 to 100%. Even worse, having too small of a value entered for duration can result in precision problems (see #4353) due to the microsecond precision on animation timers.Proposal
Allow omitting the duration for an animation driven by finite timeline.
Concretely:
auto
, the animation and timeline will have a duration / timeRange of 100 (i.e. 100%).For the above example, this would make the following valid:
And would result in a duration and timeRange of 100 (percent).
Open questions
Note: This is technically a change of the web-animations, but the reasons for it are due to finite timelines such as ScrollTimeline.
@birtles @graouts @majido WDYT? I can put together a prototype of this in my polyfill and include other examples if it would be helpful.
The text was updated successfully, but these errors were encountered: