Skip to content

Commit bebe3a0

Browse files
authored
[web-animations-1] Add advice about not using indefinitely filling animations (w3c#3901)
1 parent 3dede67 commit bebe3a0

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

web-animations-1/Overview.bs

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,67 @@ The possible <a>fill modes</a> are:
23452345
The normative definition of these modes is incorporated in the
23462346
calculation of the <a>active time</a> in [[#calculating-the-active-time]].
23472347

2348+
<div class=advisement>
2349+
<p>
2350+
Authors are discouraged from using [=fill modes=] to produce animations whose
2351+
effect is applied indefinitely.
2352+
[=Fill modes=] were introduced in order to represent the 'animation-fill-mode'
2353+
property defined by CSS animations [[CSS-ANIMATIONS-1]].
2354+
However, they produce situations where animation state would be accumulated
2355+
indefinitely necessitating the automatic removal of animations defined in
2356+
[[#replacing-animations]].
2357+
Furthermore, indefinitely filling animations can cause changes to specified
2358+
style to be ineffective long after all animations have completed since the
2359+
animation style takes precedence in the CSS cascade [[css-cascade-3]].
2360+
</p>
2361+
2362+
<p>
2363+
Where possible, authors should prefer to set the final state of the animation
2364+
directly in specified style.
2365+
This can be achieved by waiting for the animation to finish and then updating
2366+
the style as illustrated below:
2367+
</p>
2368+
2369+
<div class="example"><pre class="lang-javascript">
2370+
// In the first frame after the following animation finishes, the callback for
2371+
// the `finished` promise will run BEFORE style is updated and hence will NOT
2372+
// flicker.
2373+
elem.animate({ transform: 'translateY(100px)' }, 200).finished(() => {
2374+
elem.style.transform = 'translateY(100px)';
2375+
});
2376+
</pre></div>
2377+
2378+
<p>
2379+
Alternatively, the author may set the specified style at the start of the
2380+
animation and then animate <em>from</em> the original value
2381+
as illustrated below:
2382+
</p>
2383+
2384+
<div class="example"><pre class="lang-javascript">
2385+
elem.style.transform = 'translateY(100px)';
2386+
elem.animate({ transform: 'none', offset: 0 }, 200);
2387+
</pre></div>
2388+
2389+
Complex effects involving layering many animations on top of one another may
2390+
require temporary use of forwards fill modes to capture the final value of an
2391+
animation before canceling it.
2392+
For example:
2393+
2394+
<div class="example"><pre class="lang-javascript">
2395+
elem.addEventListener('click', async evt => {
2396+
const animation = elem.animate(
2397+
{ transform: `translate(${evt.clientX}px, ${evt.clientY}px)` },
2398+
{ duration: 800, fill: 'forwards' }
2399+
);
2400+
await animation.finished;
2401+
// commitStyles will record the style up to and including `animation` and
2402+
// update elem's specified style with the result.
2403+
animation.commitStyles();
2404+
animation.cancel();
2405+
});
2406+
</pre></div>
2407+
</div>
2408+
23482409
<h4 id="fill-modes">Fill modes</h4>
23492410

23502411
<div class='informative-bg'><em>This section is non-normative</em>
@@ -3719,7 +3780,7 @@ For example, consider the following code:
37193780
<div class="example"><pre class="lang-javascript">
37203781
elem.addEventListener('mousemove', evt => {
37213782
circle.animate(
3722-
{ transform: `translate(${evt.clientX}, ${evt.clientY})` },
3783+
{ transform: `translate(${evt.clientX}px, ${evt.clientY}px)` },
37233784
{ duration: 500, fill: 'forwards' }
37243785
);
37253786
});
@@ -4413,6 +4474,11 @@ dictionary OptionalEffectTiming {
44134474

44144475
</div>
44154476

4477+
<div class=advisement>
4478+
As described in [[#fill-behavior]], authors are discouraged from using
4479+
indefinitely filling animations.
4480+
</div>
4481+
44164482
: <dfn dict-member for=EffectTiming>iterationStart</dfn><dfn dict-member
44174483
for=OptionalEffectTiming lt=iterationStart></dfn>
44184484
:: The <a>animation effect</a>'s <a>iteration start</a> property which is a
@@ -4956,8 +5022,11 @@ It is possible to create an animation that simply sets a property
49565022
without any interpolation as follows:
49575023

49585024
<div class='example'><pre class='lang-javascript'>
4959-
var effect = new KeyframeEffect(elem, { visibility: 'hidden' }, { fill: 'forwards' });</pre></div>
5025+
var effect =
5026+
new KeyframeEffect(elem, { visibility: 'hidden' }, { fill: 'forwards' });</pre></div>
49605027

5028+
As described in [[#fill-behavior]] however, using indefinitely filling
5029+
animations in this way is discouraged.
49615030

49625031
Having created a {{KeyframeEffect}}, it can be played by adding it to
49635032
an {{Animation}} and then playing that animation.

0 commit comments

Comments
 (0)