diff --git a/scroll-animations/css/timeline-offset-in-keyframe-change-timeline.tentative.html b/scroll-animations/css/timeline-offset-in-keyframe-change-timeline.tentative.html index 6456e8aa779da7..5ac54081845605 100644 --- a/scroll-animations/css/timeline-offset-in-keyframe-change-timeline.tentative.html +++ b/scroll-animations/css/timeline-offset-in-keyframe-change-timeline.tentative.html @@ -76,7 +76,14 @@ // Initially using a document timeline, so the keyframes should be // ignored. let frames = anim.effect.getKeyframes(); - let expected = []; + let expected = [ + { offset: { rangeName: 'cover', offset: CSS.percent(0) }, + computedOffset: null, easing: "linear", composite: "auto", + marginLeft: "0px", opacity: "0" }, + { offset: { rangeName: 'cover', offset: CSS.percent(100) }, + computedOffset: null, easing: "linear", composite: "auto", + marginRight: "0px", opacity: "1" } + ]; assert_frame_lists_equal(frames, expected); // Once a view-timeline is added, the kefyrames must update to reflect @@ -88,13 +95,15 @@ frames = anim.effect.getKeyframes(); expected = [ - { offset: -1, computedOffset: -1, easing: "linear", composite: "auto", - marginLeft: "0px", opacity: "0" }, { offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginRight: "10px" }, { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginLeft: "10px" }, - { offset: 2, computedOffset: 2, easing: "linear", composite: "auto", + { offset: { rangeName: 'cover', offset: CSS.percent(0) }, + computedOffset: -1, easing: "linear", composite: "auto", + marginLeft: "0px", opacity: "0" }, + { offset: { rangeName: 'cover', offset: CSS.percent(100) }, + computedOffset: 2, easing: "linear", composite: "auto", marginRight: "0px", opacity: "1" }, ]; assert_frame_lists_equal(frames, expected); @@ -105,13 +114,15 @@ await waitForNextFrame(); frames = anim.effect.getKeyframes(); expected = [ - { offset: -1/3, computedOffset: -1/3, easing: "linear", - composite: "auto", marginLeft: "0px", opacity: "0" }, { offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginRight: "10px" }, { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginLeft: "10px" }, - { offset: 4/3, computedOffset: 4/3, easing: "linear", composite: "auto", + { offset: { rangeName: 'cover', offset: CSS.percent(0) }, + computedOffset: -1/3, easing: "linear", + composite: "auto", marginLeft: "0px", opacity: "0" }, + { offset: { rangeName: 'cover', offset: CSS.percent(100) }, + computedOffset: 4/3, easing: "linear", composite: "auto", marginRight: "0px", opacity: "1" }, ]; assert_frame_lists_equal(frames, expected); @@ -120,9 +131,15 @@ assert_equals(getComputedStyle(target).animationTimeline, 'auto', 'Switch back to document timeline'); frames = anim.effect.getKeyframes(); - expected = []; + expected = [ + { offset: { rangeName: 'cover', offset: CSS.percent(0) }, + computedOffset: null, easing: "linear", composite: "auto", + marginLeft: "0px", opacity: "0" }, + { offset: { rangeName: 'cover', offset: CSS.percent(100) }, + computedOffset: null, easing: "linear", composite: "auto", + marginRight: "0px", opacity: "1" } + ]; assert_frame_lists_equal(frames, expected); - }, 'getKeyframes with timeline-offsets'); } diff --git a/scroll-animations/css/timeline-offset-keyframes-hidden-subject.html b/scroll-animations/css/timeline-offset-keyframes-hidden-subject.html index d3b124ba18e39d..047acfed33f36a 100644 --- a/scroll-animations/css/timeline-offset-keyframes-hidden-subject.html +++ b/scroll-animations/css/timeline-offset-keyframes-hidden-subject.html @@ -68,15 +68,17 @@ let frames = anim.effect.getKeyframes(); let expected_resolved_offsets = [ - { offset: -1/3, computedOffset: -1/3, easing: "linear", - composite: "auto", marginLeft: "0px" }, { offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginRight: "10px", opacity: "1" }, { offset: 1/2, computedOffset: 1/2, easing: "linear", composite: "auto", opacity: "0.5" }, { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginLeft: "10px", opacity: "1" }, - { offset: 4/3, computedOffset: 4/3, easing: "linear", composite: "auto", + { offset: { rangeName: 'cover', offset: CSS.percent(0) }, + computedOffset: -1/3, easing: "linear", + composite: "auto", marginLeft: "0px" }, + { offset: { rangeName: 'cover', offset: CSS.percent(100) }, + computedOffset: 4/3, easing: "linear", composite: "auto", marginRight: "0px" }, ]; assert_frame_lists_equal(frames, expected_resolved_offsets, @@ -92,7 +94,13 @@ { offset: 0.5, computedOffset: 0.5, opacity: "0.5", easing: "linear", composite: "auto", }, { offset: 1, computedOffset: 1, opacity: "1", easing: "linear", - composite: "replace" } + composite: "replace" }, + { offset: { rangeName: 'cover', offset: CSS.percent(0) }, + computedOffset: null, easing: "linear", + composite: "auto", marginLeft: "0px" }, + { offset: { rangeName: 'cover', offset: CSS.percent(100) }, + computedOffset: null, easing: "linear", composite: "auto", + marginRight: "0px" } ]; assert_frame_lists_equal(frames, expected_unresolved_offsets, 'Keyframes with invalid view timeline'); diff --git a/scroll-animations/css/timeline-offset-keyframes-with-document-timeline.html b/scroll-animations/css/timeline-offset-keyframes-with-document-timeline.html index 95a0ea4eae0cbf..03ee381fd9276f 100644 --- a/scroll-animations/css/timeline-offset-keyframes-with-document-timeline.html +++ b/scroll-animations/css/timeline-offset-keyframes-with-document-timeline.html @@ -12,15 +12,15 @@ + +
+
+
+ + + diff --git a/web-animations/resources/keyframe-utils.js b/web-animations/resources/keyframe-utils.js index 8e6e5840f7f872..60fb9781a0c080 100644 --- a/web-animations/resources/keyframe-utils.js +++ b/web-animations/resources/keyframe-utils.js @@ -31,8 +31,20 @@ function assert_frames_equal(a, b, name) { `properties on ${name} should match`); // Iterates sorted keys to ensure stable failures. for (const p of Object.keys(a).sort()) { - if (typeof a[p] == 'number') + if (typeof b[p] == 'number') assert_approx_equals(a[p], b[p], 1e-6, `value for '${p}' on ${name}`); + else if (typeof b[p] == 'object') { + for (const key in b[p]) { + if (typeof b[p][key] == 'number') { + assert_approx_equals(a[p][key], b[p][key], 1e-6, + `value for '${p}.${key}' on ${name}`); + } else { + assert_equals((a[p][key] || 'undefined').toString(), + b[p][key].toString(), + `value for '${p}.${key}' on ${name}`); + } + } + } else assert_equals(a[p], b[p], `value for '${p}' on ${name}`); }