Open birtles opened 6 years ago
From @rachelnabors on May 25, 2017 18:6
Interesting thought! Questions:
anim1
in the CSS?anim1
in the CSS?anim1
in the JS and the CSS??From @dvoytenko on May 25, 2017 18:30
What if there's no anim1 in the CSS?
This would be similar to referencing an absent keyframes rule in CSS animation
property, e.g.
.x {
animation: unknown 1s;
}
This would fail to do anything in CSS, so Element.animate
could either fail or just return a no-op player. I'd prefer if it failed.
What if there're several anim1 in the CSS?
Similarly, I think it should work same as animation: anim1
in CSS. I believe the last one wins.
What if there's an anim1 in the JS and the CSS??
Could you explain this? Can a keyframes rule be in both JS and CSS?
From @rachelnabors on May 25, 2017 18:32
A keyframes object can be. What if you store a keyframes object as anim1
. The difference between the two is one is a string and the other is a variable. I do wonder if that will lead to confusion.
I also wonder: how might this break sites? Would it result in namespacing issues for CSS?
From @dvoytenko on May 25, 2017 18:41
I see. I think it's a relatively clear API separation with Element.animate(object|array)
vs Element.animate(string)
. Currently, the Element.animate(string)
simply fails with an error like this (from Chrome):
Failed to execute 'animate' on 'Element': The provided value is not of type '(sequence<Dictionary> or Dictionary)'
So, I think enabling it here could be fairly natural. And this should be backward compatible.
RE: object vs CSS name. It's basically a difference between element.animate(anim1)
where anim1
is a variable holding an array or an object as now, vs element.animate('anim1')
. Not sure if this would be too confusing.
RE: namespacing. I think it'd be ok as well. Class names and other things are used freely in JS. It's pretty common for JS APIs to rely on things already in CSS styles.
From @notoriousb1t on May 25, 2017 20:23
I like the idea of defining CSS keyframes and retrieving it, but I wonder if having a mechanism for inspecting keyframes would be better.
const anim1 = document.findKeyframesByName('anim1');
const el = document.getElementById('someId')
el.animate(anim1, /* ... */);
Passing a string to an element assumes the Element has knowledge of the global environment. I think inspecting the current document for a named keyframe object of some sort might be a less coupled approach.
I have no idea what findKeyframesByName() would return in this case, but I would assume it would be a native object.
From @dvoytenko on May 25, 2017 21:44
@notoriousb1t That would definitely work. This is probably how this feature would be polyfilled :) One reason I liked string argument is because I thought it was less ambiguous, e.g. from the point of view of media queries and such. In other words, the browser would locate, extract, apply media queries, etc to keyframes rules before running the animation. Loading all this meaning into findKeyframesByName
could be totally fine though.
Passing a string to an element assumes the Element has knowledge of the global environment.
Don't we assume that element.animate()
is sort of a shortcut to some global APIs? E.g. as the case with Document.timeline
and Animation
class?
From @notoriousb1t on May 25, 2017 21:59
It is true that Animation.timeline is assigned to the current Document.timeline. I meant that it would be better to avoid relying on globals where possible. I didn't mean element doesn't currently have access to them.
From @dvoytenko on May 26, 2017 17:15
@notoriousb1t Sure. I guess if there's a robust findKeyframesByName
- the problem is solved.
Just a few comments here:
There has been a proposal for a CSSKeyframes registry type object in the past and I agree this probably makes sense. We already have plans to allow creating keyframes from StylePropertyMap
objects (instead of SharedKeyframeList
objects) so perhaps this could just be realized as an extension to the CSSKeyframesRule
interface from the CSSOM (e.g. extend that API to give you back a StylePropertyMap
and then just feed that into the KeyframeEffect()
constructor?).
One complication is that CSS @keyframes
rules change depending on the the computed value of animation-timing-function
on the element they're applied to. The following generates two unique sets of keyframes (since the from
rule, below, does not specify animation-timing-function
):
.a {
animation: abc 2s linear;
}
.b {
animation: abc 2s ease;
}
@keyframes abc {
from { transform: translate(0px) }
to { translate: translate(100px) }
}
elem.getAnimations()
.find(anim => anim.animationName === 'abc')
.effect
.getKeyframes()
From there you can feed those keyframes into a new KeyframeEffect()
constructor, Animation()
constructor or Element.animate
call.
From @dvoytenko on June 1, 2017 19:43
@birtles I can't seem to find getAnimations()
implemented anywhere yet, so can't test with certainty, but it sounds like this will only return active animations?
Accepting keyframes from CSSKeyframesRule
sounds like a wonderful idea though. Only one nuance I mentioned above - the onus will be on a developer to properly find this rule given CSS order and media queries.
@dvoytenko getAnimations()
is implemented in Firefox Nightly and DevEdition. We're not going to ship it for a while, however, since we need to make sure the mapping between the API and CSS animations/transitions is properly specified first.
Yes, getAnimations()
only returns active, filling, or yet-to-run animations.
Yes, getting to the right CSSKeyframesRule
is a pain but I think that's largely because the CSSOM is so clumsy. Hopefully we can fix the CSSOM in future to make that easier.
From @dvoytenko on June 1, 2017 23:36
@birtles Ok, so if I kept track of everything right. A good way to support this request is by:
CSSKeyframesRule
as an input in place of keyframes effects in Element.animate()
.CSSKeyframesRule
easier.I just ran across this issue while trying to implement an API exactly like this in one of my own projects. I'd love to see it become part of the spec.
It looks like it's been some time since the last discussion on it though, and some things that have become widely available in the past seven years may make this a bit more complicated. For example, the Shadow DOM API allows for CSS encapsulation that might mean CSS keyframes with a certain name may exist for elements only in one particular shadow DOM, or only in the light DOM.
I don't think that would be a problem for an interface like this:
Element.animate(keyframes: string, options?: number | KeyframeAnimationOptions)
But it would complicate the potential option of making it easy to discover or retrieve the available CSSKeyframesRule
objects. At least, I expect that discovery would need to be done for a specific element, instead of being done directly on the document itself.
From @dvoytenko on May 25, 2017 17:24
A proposal is to extend API to accept keyframes name from a CSS style. E.g.
This would be useful because CSS syntax still provides a better way to configure keyframes than a JSON object.
Copied from original issue: w3c/web-animations#189