Open bramus opened 1 year ago
I think this would be better addressed using group effects. Adding coupling between timelines and effects seems awkward architecturally.
# I think this would be better addressed using group effects.
IUC group effects is more about grouping effects on one and the same element? How would that work across several elements?
# Adding coupling between timelines and effects seems awkward architecturally.
What I’m aiming at here is to visually sync animations across several elements. With the idea I had there’s no actual coupling between any of the timelines. Effects would still run independent from each other on the document timeline, yet appear to be synced because they all have their start time fixated to 0
(or a multiple of their duration). This approach could then also be used to align group effects across elements.
I’m very aware I could be oversimplifying things here, Brian; happy to learn what the group effects approach would (roughly) look like.
IUC group effects is more about grouping effects on one and the same element? How would that work across several elements?
Keyframe effects specify their target element so group effects (which combine keyframe effects) are able to target multiple elements.
For this particular use case, you'd specify the (infinite) iteration count on the group and then attach child effects to it. Any effects added to the group while it was in play would pick up from the group's current time and so would be synchronized with existing effects.
This seems related to https://github.com/w3c/csswg-drafts/issues/6780 also...
@birtles I think one downside to using WA2 is... how do you do this declaratively?
@birtles I think one downside to using WA2 is... how do you do this declaratively?
We need to devise the declarative form of timing groups. I wonder if a similar syntax to counters could work.
For this issue specifically, what about if any name value for animation-timeline
that wasn't bound to a declared timeline, instead of being an inactive timeline, was an automatically-generated time-based timeline? The first element to use it would create the timeline (and it would behave just like auto
does today), but all other animations that request the same timeline get bound to that same timeline. That wouldn't give you control over when exactly it starts, but it would allow you to bind a set of animations across the document all to the same timeline.
One scenario where I recently needed this was when swapping out one animation for the other, but have the second animation continue where the first one was cut.
el {
animation: one 5s linear infinite;
animation-timeline: --sync;
}
el:hover {
animation: two 5s linear infinite;
animation-timeline: --sync;
}
@fantasai: I don’t think that with your suggestion I would be able to refer to the timeline of one
to use for two
, as the former no longer exists upon hovering? Or would it be kept alive in between?
I agree with @birtles, this can and should be solved by group effects. Although the term "timeline" was used for this purpose in some libraries, e.g. GSAP, it's not the correct construct here. So this might be a source of confusion.
@bramus your example should be solved with group effects if these animations are added to same group, then they sync their progress with the group's.
For this issue specifically, what about if any name value for animation-timeline that wasn't bound to a declared timeline, instead of being an inactive timeline, was an automatically-generated time-based timeline?
We definitely need a declarative way to use group effects, though IMO using timelines here is not the correct way. We already have some mixup of animation
matching actually to KeyframeEffect
s. So trying to continue this path for using *-timeline
for groups will probably make things worse.
For example: we could specify group-timeline
will be used for declaring a group effect with a name and timing properties, like:
group-timeline: --group-a 1s linear 2s;
and then elsewhere specify animation-timeline
to use that name.
The main problem with this approach is that you can't play that group effect using a different timeline, like a ViewTimeline.
animation-group
that takes a list of idents to add an animation to a group, and possibly an integer for the order in a sequence.group-effect
, to declare a group effect that can be later used as above.The group-effect
can be just specified on a parent, which all animation-group
s just seek upwards on the tree.
The group-effect
property can be a shorthand of all properties: name
, type
, and rest of timing properties.
name
can be a dashed/custom-ident.
type
to specify group
or sequence
.
An example usage could be something along the lines of:
@keyframes slide { ... }
@keyframes blink { ... }
#container {
group-effect-TBD: --gorup-1 sequence 2.5s 0.5s linear 2;
}
#target {
animation:
slide 1s ease-out both,
blink 1.5s ease-in-out 1s infinite;
animation-group: --group-1, --group-1;
}
Once the common parent with the group-effect
is matched, that animation becomes active and starts its progress, and then the same goes for its children accordingly.
For further nesting we'll also need group-effect
to be nest-able inside another group, so the syntax also needs to account for that, though I think we can't use animation-group
again, since it's used with animation
. I suppose adding another ident to its syntax should be the way to go.
@ydaniv Thanks for kicking off the discussion about CSS syntax for group effects. That certainly seems like a good start.
When adding elements to a page, the applied animations (when not paused) start ticking forwards from the moment the elements are added. In some cases this is not wanted and authors want to keep (repeating) animations synchronized: independent of when a new elements was added, its animations need to be in sync with the other elements that use those animations.
The author of the web-based https://athenacrisis.com/ game for example mentioned this as one of the things they had to work around while building their game that uses CSS animations. As you can see in the demo video on their homepage, the game characters hover/bounce in sync with each other.
To do this today, an author currently has to resort to JavaScript:
startTime
(demo)(Step 2 needs to be reapplied as more animation effects get added)
I think there should be an easier way to do this. I was thinking of introducing a new type of timeline to solve this: the synchronised timeline. When applied, the running animation still ticks forward on the document timeline, but its start is synced to multiples of its duration or – even easier – to simply
0
.For example, say a repeating animation has a duration of
6s
and the element gets added at21.15s
into the page’s lifespan. Upon adding that element, thestartTime
for its animations is set to the preceding multiple of its duration (here18s
). That way, it’s animation is already at the3.15s
mark at first render, making it visually sync up with possible other elements that use the synchronised timeline for its animations. The animation delay would also need to be taken into account in this.A proposed notation for this type of timeline would be a new function
sync()
or maybedocument(sync)
to indicate its relation to the default document timeline.