scroll-timeline-overallProgress.tentative.html (6359B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>Animation.overallProgress</title> 4 <link rel="help" 5 href="https://drafts.csswg.org/web-animations-2/#the-overall-progress-of-an-animation"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="../../testcommon.js"></script> 9 <script src="../../../scroll-animations/scroll-timelines/testcommon.js"></script> 10 <body> 11 <style> 12 .scroller { 13 overflow-x: hidden; 14 overflow-y: auto; 15 height: 200px; 16 width: 100px; 17 will-change: transform; 18 } 19 .contents { 20 height: 1200px; 21 width: 100%; 22 } 23 #target { 24 height: 100px; 25 width: 100px; 26 background-color: green; 27 margin-top: -1000px; 28 } 29 </style> 30 <div id="log"></div> 31 <script> 32 'use strict'; 33 34 promise_test(async t => { 35 const animation = createScrollLinkedAnimation(t); 36 const scroller = animation.timeline.source; 37 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 38 39 assert_equals(animation.currentTime, null, 40 "The current time is null in Idle state."); 41 assert_equals(animation.overallProgress, null, 42 "The overallProgress is null since the currentTime is unresolved."); 43 44 animation.play(); 45 assert_true(animation.pending, "Animation is in the pending state."); 46 assert_equals(animation.currentTime, null, 47 "The current time remains null while in the pending state."); 48 assert_equals(animation.overallProgress, null, 49 "The overallProgress is null since the currentTime is unresolved."); 50 51 await animation.ready; 52 // Verify initial start and current times once ready. 53 assert_percents_equal(animation.currentTime, 0, 54 "The current time is resolved when ready."); 55 assert_equals(animation.overallProgress, 0, 56 "The overallProgress should be zero."); 57 58 scroller.scrollTop = 0.4 * maxScroll; 59 60 await waitForNextFrame(); 61 assert_percents_equal(animation.currentTime, 40, 62 "currentTime reflects overallProgress as a percentage"); 63 assert_approx_equals(animation.overallProgress, 0.4, 0.01, 64 "The overallProgress should match the scroll progress."); 65 }, "animation.overallProgress reflects the progress of a scroll animation as " + 66 "a number between 0 and 1"); 67 68 promise_test(async t => { 69 const animation = createScrollLinkedAnimation(t); 70 const scroller = animation.timeline.source; 71 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 72 73 animation.play(); 74 await animation.ready; 75 // Verify initial start and current times once ready. 76 assert_percents_equal(animation.currentTime, 0, 77 "The current time is resolved when ready."); 78 assert_equals(animation.overallProgress, 0, 79 "The overallProgress should be zero."); 80 81 scroller.scrollTop = 0.4 * maxScroll; 82 await waitForNextFrame(); 83 84 let timing = animation.effect.getComputedTiming(); 85 // iteration duration should be 100%, overallProgress should reflect 40%. 86 assert_percents_equal(timing.duration, 100); 87 assert_percents_equal(animation.currentTime, 40, 88 "currentTime reflects progress as a percentage"); 89 assert_approx_equals(animation.overallProgress, 0.4, 0.01, 90 "The overallProgress should match the scroll progress."); 91 timing = animation.effect.getComputedTiming(); 92 93 animation.effect.updateTiming({ iterations: 2 }); 94 95 timing = animation.effect.getComputedTiming(); 96 // iteration duration should be 50%, overallProgress should still reflect 40% 97 // as it measures currentTime / effect endTime. 98 assert_percents_equal(timing.duration, 50); 99 assert_percents_equal(animation.currentTime, 40, 100 "currentTime reflects progress as a percentage"); 101 assert_approx_equals(animation.overallProgress, 0.4, 0.01, 102 "The overallProgress is should match the scroll progress."); 103 }, "animation.overallProgress reflects the overall progress of a scroll " + 104 "with multiple iterations."); 105 106 promise_test(async t => { 107 const scroller = createScroller(t); 108 const view_timeline = createViewTimeline(t); 109 110 const animation = createAnimation(t); 111 animation.rangeStart = { rangeName: 'contain', offset: CSS.percent(10) }; 112 animation.rangeEnd = { rangeName: 'contain', offset: CSS.percent(90) }; 113 animation.timeline = view_timeline; 114 115 await animation.ready; 116 117 // Cover range is [0, 300] 118 // Contain range is [100, 200] 119 // rangeStart offset of 10% => 110px 120 // rangeEnd offset of 90% => 190px 121 const target_pct = 40; 122 const target_scroll_top = 110 + (target_pct / 100) * (190 - 110); 123 scroller.scrollTop = target_scroll_top; 124 await waitForNextFrame(); 125 126 const start_time = 110 / 300 * 100; 127 const timeline_time = target_scroll_top / 300 * 100; 128 const expected_current_time = timeline_time - start_time; 129 assert_percents_equal(animation.currentTime, expected_current_time, 130 "currentTime reflects progress as a percentage"); 131 assert_approx_equals(animation.overallProgress, target_pct / 100, 0.01, 132 "overallProgress should reflect fraction of view timeline range scroll " 133 + "through."); 134 }, "animation.overallProgress reflects the overall progress of a scroll " 135 + "that uses a view-timeline."); 136 137 promise_test(async t => { 138 const scroller = createScroller(t); 139 const view_timeline = createViewTimeline(t); 140 141 const animation = createAnimation(t); 142 animation.rangeStart = { rangeName: 'contain', offset: CSS.percent(10) }; 143 animation.rangeEnd = { rangeName: 'contain', offset: CSS.percent(90) }; 144 animation.timeline = view_timeline; 145 146 await animation.ready; 147 148 // Cover range is [0, 300] 149 // Contain range is [100, 200] 150 // rangeStart offset of 10% => 110px 151 // rangeEnd offset of 10% => 190px 152 153 scroller.scrollTop = 100; 154 await waitForNextFrame(); 155 let timing = animation.effect.getComputedTiming(); 156 assert_less_than(animation.currentTime.value, 0, "currentTime is negative"); 157 assert_approx_equals(animation.overallProgress, 0, 0.01, "overallProgress " + 158 "is zero when scroll offset is less than range start."); 159 160 scroller.scrollTop = 200; 161 await waitForNextFrame(); 162 assert_approx_equals(animation.currentTime.value, timing.endTime.value, 0.01, 163 "currentTime has reached endTime"); 164 assert_approx_equals(animation.overallProgress, 1, 0.01, "overallProgress " + 165 "is one when scroll offset goes past than range end."); 166 }, "overallProgress of a view-timeline is bounded between 0 and 1."); 167 168 </script> 169 </body>