csswg-drafts icon indicating copy to clipboard operation
csswg-drafts copied to clipboard

[web-animations-2] Web animations API for specifying timeline phases in animation options.

Open flackr opened this issue 2 years ago • 9 comments

As part of #7044 we resolved:

  • Add ability to specify start and end delays in terms of position in a named phase position (keyword + percentage), e.g. animation-delay: contain 0%; animation-duration: contain 100% attaches the animation between the 0% and 100% points in the contain phase. (See also https://github.com/w3c/csswg-drafts/issues/4342].)
  • Add shorthand that expands a phase name to 0% start delay and 100% end delay. E.g. animation-phase: contain expands to animation-delay: contain 0%; animation-end-delay: contain 100%.

These resolutions specify how in CSS you can target an animation to a particular phase of the view timeline. However, we also need a way to do the same from the web animations API. In particular the options passed for the timing of web animations are EffectTiming and OptionalEffectTiming.

Here are a few options I can think of:

  1. The simplest would be to extend the delay and endDelay options to also accept a string specification equivalent to the CSS counterpart (e.g. delay: "enter 20%").
  2. Extend delay and endDelay to also accept an object type representing the combination of phase and time, e.g. delay: {phase: "enter"}, offset: CSS.percentage(20)}.
  3. Add new options, e.g. startTime / endTime or phase for specifying the "phase", "time" pairs. We would then have to decide what to do when delay and endDelay are also specified.

flackr avatar Aug 10 '22 16:08 flackr

Leaning towards option 1 as it seems easier for the web developer (less verbose than option 2 and avoids potential confusion due to over-specification with option 3).

kevers-google avatar Aug 10 '22 17:08 kevers-google

Also leaning towards 1, as authors expect the css animations and web animations APIs to reflect each other as much as possible.

ydaniv avatar Aug 10 '22 18:08 ydaniv

Option 1 certainly seems the most straightforward, though option 2 is more consistent with the direction we've been trying to move in terms of having full rich types for the things that are expressed as strings in CSS.

Regardless of option (1) or (2), we will still have similar over-specification issues if we also allow specifying non-"auto" durations e.g. #4342. I think we'll just have to choose a precedent - probably try to align this with what happens when you specify left, right and width on an element size.

flackr avatar Aug 10 '22 20:08 flackr

@birtles @graouts FYI

flackr avatar Aug 11 '22 12:08 flackr

Another variant of 2 would be a new unit type to represent the phase + percentage pair, e.g. delay: CSS.PhasePercent('enter', 20) - though probably not under CSS given it's not a CSSNumber?

flackr avatar Aug 11 '22 18:08 flackr

Option 1 seems fine to me. I really want to avoid having phase as a mutable property (1, 2).

We could possibly introduce option 2 (or the variant you mentioned) at a later point if it proves necessary?

birtles avatar Aug 12 '22 02:08 birtles

I really want to avoid having phase as a mutable property (1, 2).

Yeah I'm hoping to bikeshed that on #7044 or possibly open a specific issue to bikeshed it. I've added a comment there.

flackr avatar Aug 16 '22 20:08 flackr

The one downside to starting with option 1 is that if this is the string value is what you read back from getTiming then we can't upgrade to option 2 without risking breaking content.

flackr avatar Aug 23 '22 17:08 flackr

The one downside to starting with option 1 is that if this is the string value is what you read back from getTiming then we can't upgrade to option 2 without risking breaking content.

Yeah, I mean we could introduce parallel properties -- typed and untyped/string-type -- and precedence rules for when they're both set, but then we'd break code that attempts to roundtrip the values, by fetching the timing, setting only the lower precedence one (e.g. the untyped/string-type one), then re-setting it.

birtles avatar Aug 24 '22 00:08 birtles

The CSS Working Group just discussed specifying timeline phases in WAAPI, and agreed to the following:

  • RESOLVED: Go with option 2 (object/Typed OM value to specify the phase+offset), details tbd by editors
The full IRC log of that discussion <TabAtkins> Topic: specifying timeline phases in WAAPI
<TabAtkins> github: https://github.com/w3c/csswg-drafts/issues/7589
<TabAtkins> flackr: We've resolved on a CSS syntax for timeline phases, where you can tie an animation to a phase
<TabAtkins> flackr: But we didn't talk about how this would work in waapi
<TabAtkins> flackr: So, how do you make a WEb Animation that animates in a particular timeline phase?
<TabAtkins> flackr: Main two proposals are (1) extend .delay and .endDelay properties, which map to equivalent css properties
<TabAtkins> flackr: These accept doubles currenty, would need to bea ble to take something expressing a phase+proportion
<TabAtkins> flackr: Advantage of option 1 is it's easy to udnerstand
<TabAtkins> flackr: Option 2 is more in line with the desire to use typed properties in these JS bindings
<TabAtkins> flackr: so we don't ahve to parse strings all the time
<TabAtkins> flackr: I think Brian is on board with either
<Rossen_> q?
<TabAtkins> flackr: I have a slight preference for option 2, as it's more future-proof. Requires some wrapper around the fields, and there's a naming question
<TabAtkins> TabAtkins: I'm fine with option 2, with details tbd by editors
<TabAtkins> Rossen_: reading thru comments, Brian seems to supportive as well
<TabAtkins> flackr: yeah, he doesn't seem worried about the string complexity, but had no objections to option 2
<TabAtkins> Rossen_: so current proposal is option 2
<TabAtkins> Rossen_: Not hearing much other opinions
<TabAtkins> Rossen_: so suggest resolving on the direction
<bramus> SGTM
<TabAtkins> Rossen_: complaints, objections?
<TabAtkins> RESOLVED: Go with option 2 (object/Typed OM value to specify the phase+offset), details tbd by editors

css-meeting-bot avatar Aug 31 '22 16:08 css-meeting-bot

My strawman proposal for the object would be accepting something like the following for delay and endDelay:

dictionary TimelineRangeOffset {
  CSSOMString? rangeName;
  CSSNumericValue offset;
}

The name TimelineRangeOffset is based on the term name from #7701 but this could also be AnimationDelay, TimelineRange, or something else more appropriate.

Using a CSSNumericValue would in theory allow for arbitrary offsets from the start / end of a range, e.g. calc(100% + 10px). Also, without a range name specified this would allow specifying offsets such as CSS.px(50) (e.g. which should support #7575 #7296 #4342).

Note that in the context of keyframe offsets #7637 the offset name does feel a bit redundant, e.g.

element.animate([
  {opacity: 0, offset: { offset: CSS.percent(20) }},
  {opacity: 1, offset: { offset: CSS.percent(80) }}], {
    delay: { rangeName: 'enter', offset: CSS.percent(0) },
    endDelay: { rangeName: 'enter', offset: CSS.percent(100) },
  });

flackr avatar Sep 13 '22 20:09 flackr

Note that in the context of keyframe offsets https://github.com/w3c/csswg-drafts/issues/7637 the offset name does feel a bit redundant, e.g.

Could you have the API automatically wrap a raw CSSNumericValue around a TimelineOffset with a null rangeName?

fantasai avatar Oct 31 '22 16:10 fantasai

Could you have the API automatically wrap a raw CSSNumericValue around a TimelineOffset with a null rangeName?

If I'm following correctly, the idea is that if you specify a TimelineOffset with null rangeName it would effectively use that TimelineOffset's inner offset value? Seems reasonable.

flackr avatar Nov 02 '22 23:11 flackr

@flackr No, what I was wondering was if we could collapse your example:

element.animate([
  {opacity: 0, offset: { offset: CSS.percent(20) }},
  {opacity: 1, offset: { offset: CSS.percent(80) }}], {
    delay: { rangeName: 'enter', offset: CSS.percent(0) },
    endDelay: { rangeName: 'enter', offset: CSS.percent(100) },
  });

down to

element.animate([
  {opacity: 0, offset: CSS.percent(20)},
  {opacity: 1, offset: CSS.percent(80)}], {
    delay: { rangeName: 'enter', offset: CSS.percent(0) },
    endDelay: { rangeName: 'enter', offset: CSS.percent(100) },
  });

(I'm not familiar with WebIDL and JS, so my main frame of reference is C++, thus all the stupid questions...)

fantasai avatar Nov 07 '22 19:11 fantasai

Gotcha, I think this would just be accepting TimelineRangeOffset or CSSNumberish and then when we parse the arguments in C++ we could determine the type of the passed value.

flackr avatar Nov 08 '22 15:11 flackr

Based on the resolution in #7901 animation-range should be set with a new set of properties. As a new set of properties we don't have to support legacy values. Based on the resolution in #7748 we should aim for accepting a string equivalent to the CSS syntax or typed OM. Rough proposal, add the following to KeyframeAnimationOptions:

dictionary TimelineRangeOffset {
  CSSOMString? rangeName;
  CSSNumericValue offset;
}
DOMString or TimelineRangeOffset rangeStart = "auto";
DOMString or TimelineRangeOffset rangeEnd = "auto";

DOMStrings would be parsed the same as the CSS animation-range-start and animation-range-end properties, as <timeline-range-name>? <percentage> | "auto".

(Edited to reflect discussion)

flackr avatar Jan 12 '23 18:01 flackr

I thought the idea was that animation-range would be a property of the animation, not the effect?

birtles avatar Jan 13 '23 00:01 birtles

I thought since this is part of determining the effect start and end times on the timeline that it made sense here, but from a usability standpoint it'd be fine to have as part of KeyframeAnimationOptions instead. It just means you don't update it with updateTiming.

flackr avatar Jan 13 '23 01:01 flackr

I think the question is, what should happen with regard to nested effects like GroupEffect and SequenceEffect?

I think it makes sense that you set up the animation range on the root Animation (since the Animation is the thing that binds us to a timeline and a range is specific to a timeline) and the result of that is applied to the Animation's root effect.

birtles avatar Jan 13 '23 01:01 birtles

Yeah that's a good point. In the context of GroupEffect and SequenceEffect it probably makes more sense to put on the Animation so that it can set the range for the root effect and result in the group or sequence covering that range. So the proposal is then https://github.com/w3c/csswg-drafts/issues/7589#issuecomment-1380842759 but added to KeyframeAnimationOptions.

flackr avatar Jan 13 '23 02:01 flackr

The CSS Working Group just discussed [web-animations-2] Web animations API for specifying timeline phases in animation options., and agreed to the following:

  • RESOLVED: take the api shape int he linked comments and add properties to the animation interface along timeline
The full IRC log of that discussion <argyle> astearns: first is about timeline phases, assuming rob is going tot ake this one
<argyle> flackr: lemme make things nice and simple..
<flackr> Proposed resolution in https://github.com/w3c/csswg-drafts/issues/7589#issuecomment-1380842759
<argyle> flackr: there's a proposed resolution int eh comment i linked
<ydaniv> s/int eh/in the/
<argyle> flackr: this isadding the ability to the web animations API to specify ranged names and offsets whciih we have already specced for css animations
<argyle> flackr: brian has looked at this proposed and agrees with the current designb, seems fine to add this to the animation options alongside the timeline attribute
<argyle> flackr: this shoudl allow us to control the same thhings from javascript animations
<argyle> flackr: any objections to the proposal?
<argyle> astearns: i'mm looking througgh, we resolved to go with option 2. the propsed shape is?
<astearns> https://github.com/w3c/csswg-drafts/issues/7589#issuecomment-1380842759
<argyle> flackr: its all consistentent with the earlier resolution, but it's not going to end delay and start delay because we moved it to it's own property
<argyle> astearns: its in this comment here?
<argyle> astearns: yep, this is it
<argyle> astearns: alright, any opinions, concerns?
<argyle> kevin ellis: moving from timing otpoins to animation options, would no logner be able to update range start/end updating timing
<argyle> kevin ellis: we will need web animation api calls on the a nimation object to be able to get range start/end
<argyle> kevin ellis: do we have a proposal for getter/setter or function for setting animation range programatically?
<argyle> flackr: conventionally we'd do the same thing as animation timeline. getter/setter
<argyle> kevin ellis: i'm in support of that, would like to see resolution
<argyle> flackr: happy to make that part of the resolution
<argyle> astearns: any other comments?
<argyle> astearns: any concern with resolving ono this today?
<argyle> astearns: proposed is to take the api shape in the linekd comment and add properties to the animation interface along timeline
<bramus> SGTM
<argyle> astearns: any objections to the propsoed resolution?
<argyle> astearns: hearing none, we are resolved
<argyle> RESOLVE: take the api shape int he linked comments and add properties to the animation interface along timeline
<argyle> RESOLVEd: take the api shape int he linked comments and add properties to the animation interface along timeline
<argyle> RESOLVED: take the api shape int he linked comments and add properties to the animation interface along timeline
<argyle> astearns: anything more on this one?

css-meeting-bot avatar Feb 01 '23 17:02 css-meeting-bot

I believe this is resolved now with 52b620ffd4364680eedf23cb72738dee671ef44c landed.

flackr avatar Apr 05 '23 19:04 flackr