Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /web-animations/animation-model/keyframe-effects/effect-value-replaced-animations.html - WPT Dashboard Interop Dashboard
<!doctype html>
<meta charset=utf-8>
<title>The effect value of a keyframe effect: Overlapping keyframes</title>
<link rel="help" href="https://drafts.csswg.org/web-animations/#the-effect-value-of-a-keyframe-animation-effect">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
function assert_opacity_value(opacity, expected, description) {
return assert_approx_equals(
parseFloat(opacity),
expected,
0.0001,
description
);
}
promise_test(async t => {
const div = createDiv(t);
div.style.opacity = '0.1';
const animA = div.animate(
{ opacity: 0.2 },
{ duration: 1, fill: 'forwards' }
);
const animB = div.animate(
{ opacity: 0.3 },
{ duration: 1, fill: 'forwards' }
);
await animA.finished;
// Sanity check
assert_equals(animA.replaceState, 'removed');
assert_equals(animB.replaceState, 'active');
// animA is now removed so if we cancel animB, we should go back to the
// underlying value
animB.cancel();
assert_opacity_value(
getComputedStyle(div).opacity,
0.1,
'Opacity should be the un-animated value'
);
}, 'Removed animations do not contribute to animated style');
promise_test(async t => {
const div = createDiv(t);
div.style.opacity = '0.1';
const animA = div.animate(
{ opacity: 0.2 },
{ duration: 1, fill: 'forwards' }
);
const animB = div.animate(
{ opacity: 0.3, composite: 'add' },
{ duration: 1, fill: 'forwards' }
);
await animA.finished;
// Sanity check
assert_equals(animA.replaceState, 'removed');
assert_equals(animB.replaceState, 'active');
// animA has been removed so the final result should be 0.1 + 0.3 = 0.4.
// (If animA were not removed it would be 0.2 + 0.3 = 0.5.)
assert_opacity_value(
getComputedStyle(div).opacity,
0.4,
'Opacity value should not include the removed animation'
);
}, 'Removed animations do not contribute to the effect stack');
promise_test(async t => {
const div = createDiv(t);
div.style.opacity = '0.1';
const animA = div.animate(
{ opacity: 0.2 },
{ duration: 1, fill: 'forwards' }
);
const animB = div.animate(
{ opacity: 0.3 },
{ duration: 1, fill: 'forwards' }
);
await animA.finished;
animA.persist();
animB.cancel();
assert_opacity_value(
getComputedStyle(div).opacity,
0.2,
"Opacity should be the persisted animation's value"
);
}, 'Persisted animations contribute to animated style');
promise_test(async t => {
const div = createDiv(t);
div.style.opacity = '0.1';
const animA = div.animate(
{ opacity: 0.2 },
{ duration: 1, fill: 'forwards' }
);
const animB = div.animate(
{ opacity: 0.3, composite: 'add' },
{ duration: 1, fill: 'forwards' }
);
await animA.finished;
assert_opacity_value(
getComputedStyle(div).opacity,
0.4,
'Opacity value should NOT include the contribution of the removed animation'
);
animA.persist();
assert_opacity_value(
getComputedStyle(div).opacity,
0.5,
'Opacity value should include the contribution of the persisted animation'
);
}, 'Persisted animations contribute to the effect stack');
promise_test(async t => {
const div = createDiv(t);
div.style.opacity = '0.1';
const animA = div.animate(
{ opacity: 0.2 },
{ duration: 1, fill: 'forwards' }
);
// Persist the animation before it finishes (and before it would otherwise be
// removed).
animA.persist();
const animB = div.animate(
{ opacity: 0.3, composite: 'add' },
{ duration: 1, fill: 'forwards' }
);
await animA.finished;
assert_opacity_value(
getComputedStyle(div).opacity,
0.5,
'Opacity value should include the contribution of the persisted animation'
);
}, 'Animations persisted before they would be removed contribute to the'
+ ' effect stack');
</script>
</body>