Open ydaniv opened 8 months ago
Looks great. I think this approach allows the start times to be staggered using, e.g. a logarithmic function, without requiring the same sort of easing apply to the duration of each child animation.
That is, in some cases you'll want the whole scene to progressively get faster in which case you can apply easing to the group. That way the start times will get progressively closer together and the child durations will get progressively shorter.
In other cases, however, you want to maintain the same duration for each child animation but simply have their start times get progressively closer together.
I think the approach you've outlined allows both effects to be achieved.
Having part of the group-effect-align
shorthand map to the parent group and part map to the children is a little odd, but we already do something similar with animations where part of the animation
shorthand (animation-play-state
) maps to the CSSAnimation
object while the rest maps to the KeyframeEffect
object.
Just to check, I believe you are proposing that group-effect-align-offset
will be computed into the delay
of the corresponding CSSAnimation
objects' KeyframeEffect
s such that JS authors won't have to try to serialize/parse strings like start calc(100ms * log(effect-count - effect-index + 1))
. To produce a similar stagger effect in JS, authors would use JS math functions to calculate the appropriate delays.
Thanks @birtles!
I think the approach you've outlined allows both effects to be achieved.
Yes, I didn't think about the group easing in this case, but yes, I think you could specify a value like the "static stagger" example above and the easing on top would take care of that.
Having part of the group-effect-align shorthand map to the parent group and part map to the children is a little odd
I didn't see it that way. I did follow your "flexbox" model here, so -type
is used for justifying and -offset
for extra margins. This could be odd, but these properties have no sense outside the context of a group, so specifying the offset independently losses that context, i.e. the context required for staggering.
Just to check, I believe you are proposing that
group-effect-align-offset
will be computed into the delay of the correspondingCSSAnimation
objects'KeyframeEffect
s such that JS authors won't have to try to serialize/parse strings like start calc(100ms * log(effect-count - effect-index + 1))
The intent was to append the result of -offset
per child to the child's own delay
or endDelay
correspondingly. So that if for some reason you specified both they would be respected.
And yes, since staggering becomes very cumbersome when you need to specify delay per element, and also because it only becomes meaningful in the context of a group.
To produce a similar stagger effect in JS, authors would use JS math functions to calculate the appropriate delays.
Yes, most libraries allow a stagger function just for that. The intent is to replace that with calc()
, math functions, and the effect-index
and effect-count
that should provide the missing arguments that these functions usually take.
Aren't effect-index
and effect-count
essentially duplicates to sibling-count()
and sibling-index()
. Most of the examples for those two were exactly what is stated here. I don't really see the difference at first glance.
@Que-tin effect-index
and effect-count
reference index and count of child effects inside an EffectGroup. They're values and not selectors. They don't reference DOM elements. I just used the "sibling" case as reference, as a convention.
Oops, I had a mistake above, sibling-*()
functions are also values, not selectors, but they do refer to sibling elements and follow DOM structure, while effect-*
values proposed above reference effects in the group.
This is a proposal for syntax that allows staggering of child effects in a
GroupEffect
by expanding thegroup-effect-align
property proposed in #9554 by making it a shorthand of 2 properties, plus introducing 2 new values (TBB):effect-index
andeffect-count
.Description
The previously proposed
group-effect-align
property, for controlling synchronization of child effects inside the group, will become a shorthand of 2 sub properties:-type
and-offset
.group-effect-align-type
This property behaves same as described here, with the addition of splitting the parallel behavior of "GroupEffect" to
start
andend
, which aligns the child effects to either start or end together respectively. It has the following possible values:start
: align all effects to start simultaneously.end
: align all effects to end simultaneously.sequence
: align each subsequent effect's start to the end of its preceding effect.sequence-reverse
: same assequence
but with descending order, so each effect's start is aligned to its succeeding effect.group-effect-align-offset
This property allows specifying an additional delay offset that is added to to each child in the group. The extra delay offset is added either to the start delay, or the end delay if
-type
is set toend
.effect-index
andeffect-count
The purpose of the
-offset
property is mostly to enable staggering effects. To enable expressive staggering effects and reuse existing CSS math functions I propose adding 2 new identity values:effect-index
andeffect-count
to reference the index of the child and count of children in the group respectively. Ifsequence
orsequence-reverse
are used, the-offset
property can still apply by offsetting each child effect relative to its normal position.Examples
Proposed syntax
I'm assuming there may be some pushback from developers expecting to see a "stagger" property. However, after reviewing various stagger implementations in some of the prominent animation libraries it seems that the API always implicitly assumes a form of
index * <number>
by simply allowing a number as a value, e.g.stagger: 0.1
. Later this complicates the API further by having to indirectly specify other properties like "from", "ease", etc, which IMO are a bit implicit and "magical", and less suitable for a low-level web API. I think that by not assuming the above form we can achieve a more flexible and explicit API, which can better leverage existing CSS math functions and values.