summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/web-animations/animation-model/combining-effects
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/web-animations/animation-model/combining-effects
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/web-animations/animation-model/combining-effects')
-rw-r--r--testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-interpolated-transform.html87
-rw-r--r--testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-the-composited-result.html29
-rw-r--r--testing/web-platform/tests/web-animations/animation-model/combining-effects/effect-composition.html154
3 files changed, 270 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-interpolated-transform.html b/testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-interpolated-transform.html
new file mode 100644
index 0000000000..c101b5f0cf
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-interpolated-transform.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title> apply interpolated transform on multiple keyframes</title>
+<link rel="help" href="https://drafts.csswg.org/web-animations/#keyframes-section">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<div id="target"></div>
+<script>
+'use strict';
+// This test tests the correctness if animation behavior under
+// box-size-denpendent and non-box-size-dependent transformation.
+test(t => {
+ var div_1 = createDiv(t);
+ div_1.style.width = "100px";
+ // Non-pairwise compatible transforms that are effectively no-ops with a
+ // matrix fallback. Both rotate(360deg) and scale(1) are identity matrix,
+ // making it easy to compute.
+ const keyframe1 = [
+ {"transform":"translateX( 200px ) rotate( 360deg )"},
+ {"transform":"translateX( 100% ) scale( 1 )"},
+ ];
+ const keyframe2 = [
+ {"transform":"translateX( 200px ) rotate( 360deg )"},
+ {"transform":"translateX( 100% ) scale( 1 )"},
+ {"transform":"none"},
+ {}
+ ];
+
+ const animation1 = div_1.animate(keyframe1, {
+ "duration":3000,
+ "easing":"linear",
+ });
+ const animation2 = div_1.animate(keyframe2, {
+ "duration":3000,
+ "easing":"linear",
+ });
+ // new animation on the second div, using px value instead of % as a reference
+
+ var div_2 = createDiv(t);
+ div_2.style.width = "100px";
+ const keyframe3 = [
+ {"transform":"translateX( 200px ) rotate( 360deg )"},
+ {"transform":"translateX( 100px ) scale( 1 )"},
+ ];
+ const keyframe4 = [
+ {"transform":"translateX( 200px ) rotate( 360deg )"},
+ {"transform":"translateX( 100px ) scale( 1 )"},
+ {"transform":"none"},
+ {}
+ ];
+
+ const animation3 = div_2.animate(keyframe1, {
+ "duration":3000,
+ "easing":"linear",
+ });
+ const animation4 = div_2.animate(keyframe2, {
+ "duration":3000,
+ "easing":"linear",
+ "composite": 'replace',
+ });
+ animation1.pause();
+ animation2.pause();
+ animation3.pause();
+ animation4.pause();
+ var i;
+ for (i = 0; i <= 30; i++) {
+ animation2.currentTime = 100 * i;
+ animation4.currentTime = 100 * i;
+ var box_size_dependent_transform = getComputedStyle(div_1)['transform'];
+ var reference_transform = getComputedStyle(div_2)['transform']
+ var progress = i / 30;
+ // The second animation replaces the first animation. As the rotate and
+ // scale perations are effectively no-ops when the matrix fallback is
+ // applied. The expected behavior is to go from x-postion 200px to 0 in the
+ // first 2000ms and go back to x-position 200px in the last 1000ms.
+ var expected_transform = 'matrix(1, 0, 0, 1, $1, 0)'
+ .replace('$1', Math.max(200 - 300 * progress, 0)
+ + Math.max(0, -400 + 600 * progress));
+ assert_matrix_equals(box_size_dependent_transform, reference_transform);
+ assert_matrix_equals(reference_transform, expected_transform);
+ }
+})
+</script>
+</body>
diff --git a/testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-the-composited-result.html b/testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-the-composited-result.html
new file mode 100644
index 0000000000..336115e577
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/animation-model/combining-effects/applying-the-composited-result.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Applying the composited result</title>
+<link rel="help"
+ href="https://drafts.csswg.org/web-animations-1/#applying-the-composited-result">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="../../testcommon.js"></script>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(async t => {
+ const div = createDiv(t);
+ div.style.marginLeft = '10px';
+ const animation = div.animate(
+ { marginLeft: ['100px', '200px'] },
+ 100 * MS_PER_SEC
+ );
+ await animation.ready;
+
+ animation.finish();
+
+ const marginLeft = parseFloat(getComputedStyle(div).marginLeft);
+ assert_equals(marginLeft, 10, 'The computed style should be reset');
+}, 'Finishing an animation that does not fill forwards causes its animation'
+ + ' style to be cleared');
+
+</script>
diff --git a/testing/web-platform/tests/web-animations/animation-model/combining-effects/effect-composition.html b/testing/web-platform/tests/web-animations/animation-model/combining-effects/effect-composition.html
new file mode 100644
index 0000000000..70a8cdd92c
--- /dev/null
+++ b/testing/web-platform/tests/web-animations/animation-model/combining-effects/effect-composition.html
@@ -0,0 +1,154 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Effect composition</title>
+<link rel="help" href="https://drafts.csswg.org/web-animations/#effect-composition">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="../../testcommon.js"></script>
+<div id="log"></div>
+<script>
+'use strict';
+
+for (const composite of ['accumulate', 'add']) {
+ test(t => {
+ const div = createDiv(t);
+ div.style.marginLeft = '10px';
+ const anim =
+ div.animate({ marginLeft: ['0px', '10px'], composite }, 100);
+
+ anim.currentTime = 50;
+ assert_equals(getComputedStyle(div).marginLeft, '15px',
+ 'Animated margin-left style at 50%');
+ }, `${composite} onto the base value`);
+
+ test(t => {
+ const div = createDiv(t);
+ div.style.marginLeft = '10px';
+ const anim =
+ div.animate([{ marginLeft: '20px', offset: 0.25 }, { marginLeft: '30px', offset: 0.75 }],
+ { duration: 100, composite });
+
+ anim.currentTime = 50;
+ assert_equals(getComputedStyle(div).marginLeft, '35px',
+ 'Animated margin-left style at 50%');
+ }, `${composite} onto the base value when the interval does not include the 0 or 1 keyframe`);
+
+ test(t => {
+ const div = createDiv(t);
+ const anims = [];
+ anims.push(div.animate({ marginLeft: ['10px', '20px'],
+ composite: 'replace' },
+ 100));
+ anims.push(div.animate({ marginLeft: ['0px', '10px'],
+ composite },
+ 100));
+
+ for (const anim of anims) {
+ anim.currentTime = 50;
+ }
+
+ assert_equals(getComputedStyle(div).marginLeft, '20px',
+ 'Animated style at 50%');
+ }, `${composite} onto an underlying animation value`);
+
+ test(t => {
+ const div = createDiv(t);
+ const anims = [];
+ anims.push(div.animate({ transform: 'translateX(100px)' }, { duration: 100, composite: 'replace' }));
+ anims.push(div.animate({ transform: 'translateY(100px)' }, { duration: 100, composite }));
+
+ for (const anim of anims) {
+ anim.currentTime = 50;
+ }
+
+ assert_equals(getComputedStyle(div).transform, 'matrix(1, 0, 0, 1, 50, 50)',
+ 'Animated style at 50%');
+ }, `${composite} onto an underlying animation value with implicit from values`);
+
+ test(t => {
+ const div = createDiv(t);
+ const anims = [];
+ anims.push(div.animate([{ offset: 1, transform: 'translateX(100px)' }], { duration: 100, composite: 'replace' }));
+ anims.push(div.animate([{ offset: 1, transform: 'translateY(100px)' }], { duration: 100, composite }));
+
+ for (const anim of anims) {
+ anim.currentTime = 50;
+ }
+
+ assert_equals(getComputedStyle(div).transform, 'matrix(1, 0, 0, 1, 50, 50)',
+ 'Animated style at 50%');
+ }, `${composite} onto an underlying animation value with implicit to values`);
+
+ test(t => {
+ const div = createDiv(t);
+ div.style.marginLeft = '10px';
+ const anim =
+ div.animate([{ marginLeft: '10px', composite },
+ { marginLeft: '30px', composite: 'replace' }],
+ 100);
+
+ anim.currentTime = 50;
+ assert_equals(getComputedStyle(div).marginLeft, '25px',
+ 'Animated style at 50%');
+ }, `Composite when mixing ${composite} and replace`);
+
+ test(t => {
+ const div = createDiv(t);
+ div.style.marginLeft = '10px';
+ const anim =
+ div.animate([{ marginLeft: '10px', composite: 'replace' },
+ { marginLeft: '20px' }],
+ { duration: 100 , composite });
+
+ anim.currentTime = 50;
+ assert_equals(getComputedStyle(div).marginLeft, '20px',
+ 'Animated style at 50%');
+ }, `${composite} specified on a keyframe overrides the composite mode of`
+ + ' the effect');
+
+ test(t => {
+ const div = createDiv(t);
+ div.style.marginLeft = '10px';
+ const anim =
+ div.animate([{ marginLeft: '10px', composite: 'replace' },
+ { marginLeft: '20px' }],
+ 100);
+
+ anim.effect.composite = composite;
+ anim.currentTime = 50; // (10 + (10 + 20)) * 0.5
+ assert_equals(getComputedStyle(div).marginLeft, '20px',
+ 'Animated style at 50%');
+ }, 'unspecified composite mode on a keyframe is overriden by setting'
+ + ` ${composite} of the effect`);
+}
+
+test(t => {
+ const div = createDiv(t);
+ const anims = [];
+ anims.push(div.animate({ marginLeft: ['10px', '20px'],
+ composite: 'replace' },
+ 100));
+ anims.push(div.animate({ marginLeft: ['0px', '10px'],
+ composite: 'add' },
+ 100));
+ // This should fully replace the previous effects.
+ anims.push(div.animate({ marginLeft: ['20px', '30px'],
+ composite: 'replace' },
+ 100));
+ anims.push(div.animate({ marginLeft: ['30px', '40px'],
+ composite: 'add' },
+ 100));
+
+ for (const anim of anims) {
+ anim.currentTime = 50;
+ }
+
+ // The result of applying the above effect stack is:
+ // underlying = 0.5 * 20 + 0.5 * 30 = 25
+ // result = 0.5 * (underlying + 30px) + 0.5 * (underlying + 40px)
+ // = 60
+ assert_equals(getComputedStyle(div).marginLeft, '60px',
+ 'Animated style at 50%');
+}, 'Composite replace fully replaces the underlying animation value');
+
+</script>