setting-current-time.html (10360B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>Setting the current time of an animation</title> 4 <link rel="help" href="https://drafts.csswg.org/web-animations-1/#setting-the-current-time-of-an-animation"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/web-animations/testcommon.js"></script> 8 <script src="testcommon.js"></script> 9 <style> 10 .scroller { 11 overflow: auto; 12 height: 200px; 13 width: 100px; 14 will-change: transform; 15 } 16 .contents { 17 height: 1000px; 18 width: 100%; 19 } 20 </style> 21 <body> 22 <div id="log"></div> 23 <script> 24 'use strict'; 25 26 promise_test(async t => { 27 const animation = createScrollLinkedAnimation(t); 28 const scroller = animation.timeline.source; 29 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 30 scroller.scrollTop = 0.25 * maxScroll; 31 // Wait for new animation frame which allows the timeline to compute new 32 // current time. 33 await waitForNextFrame(); 34 animation.play(); 35 36 await animation.ready; 37 38 assert_throws_js(TypeError, () => { 39 animation.currentTime = null; 40 }); 41 }, 'Setting animation current time to null throws TypeError.'); 42 43 promise_test(async t => { 44 const animation = createScrollLinkedAnimation(t); 45 assert_throws_js(TypeError, () => { 46 animation.currentTime = CSSNumericValue.parse("300"); 47 }); 48 assert_throws_js(TypeError, () => { 49 animation.currentTime = CSSNumericValue.parse("300ms"); 50 }); 51 assert_throws_js(TypeError, () => { 52 animation.currentTime = CSSNumericValue.parse("0.3s"); 53 }); 54 }, 'Setting the current time to an absolute time value throws exception'); 55 56 promise_test(async t => { 57 const animation = createScrollLinkedAnimation(t); 58 const scroller = animation.timeline.source; 59 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 60 scroller.scrollTop = 0.25 * maxScroll; 61 // Wait for new animation frame which allows the timeline to compute new 62 // current time. 63 await waitForNextFrame(); 64 65 animation.currentTime = CSSNumericValue.parse("33.3%"); 66 67 assert_percents_equal(animation.currentTime, 33.3, 68 "Animation current time should be equal to the set value." 69 ); 70 }, 'Set animation current time to a valid value without playing.'); 71 72 promise_test(async t => { 73 const animation = createScrollLinkedAnimation(t); 74 const scroller = animation.timeline.source; 75 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 76 scroller.scrollTop = 0.25 * maxScroll; 77 // Wait for new animation frame which allows the timeline to compute new 78 // current time. 79 await waitForNextFrame(); 80 animation.play(); 81 82 await animation.ready; 83 animation.currentTime = CSSNumericValue.parse("33.3%"); 84 85 assert_percents_equal(animation.currentTime, 33.3, 86 "Animation current time should be equal to the set value." 87 ); 88 }, 'Set animation current time to a valid value while playing.'); 89 90 promise_test(async t => { 91 const animation = createScrollLinkedAnimation(t); 92 const scroller = animation.timeline.source; 93 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 94 scroller.scrollTop = 0.25 * maxScroll; 95 // Wait for new animation frame which allows the timeline to compute new 96 // current time. 97 await waitForNextFrame(); 98 animation.play(); 99 100 await animation.ready; 101 animation.currentTime = CSSNumericValue.parse("200%"); 102 103 assert_equals(animation.playState, "finished"); 104 assert_percents_equal(animation.currentTime, 200, 105 "Animation current time should be equal to the set value." 106 ); 107 }, 'Set animation current time to a value beyond effect end.'); 108 109 promise_test(async t => { 110 const animation = createScrollLinkedAnimation(t); 111 const scroller = animation.timeline.source; 112 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 113 scroller.scrollTop = 0.25 * maxScroll; 114 // Wait for new animation frame which allows the timeline to compute new 115 // current time. 116 await waitForNextFrame(); 117 animation.play(); 118 119 await animation.ready; 120 animation.currentTime = CSSNumericValue.parse("-10%"); 121 122 assert_equals(animation.playState, "running"); 123 assert_percents_equal(animation.currentTime, -10, 124 "Animation current time should be equal to the set value." 125 ); 126 }, 'Set animation current time to a negative value.'); 127 128 promise_test(async t => { 129 const animation = createScrollLinkedAnimation(t); 130 const scroller = animation.timeline.source; 131 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 132 scroller.scrollTop = 0.25 * maxScroll; 133 // Wait for new animation frame which allows the timeline to compute new 134 // current time. 135 await waitForNextFrame(); 136 animation.play(); 137 138 animation.currentTime = CSSNumericValue.parse("30%"); 139 140 assert_equals(animation.playState, "running"); 141 assert_true(animation.pending); 142 assert_percents_equal(animation.currentTime, 30); 143 }, "Setting current time while play pending overrides the current time"); 144 145 promise_test(async t => { 146 const animation = createScrollLinkedAnimation(t); 147 const scroller = animation.timeline.source; 148 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 149 scroller.scrollTop = 0.25 * maxScroll; 150 // Wait for new animation frame which allows the timeline to compute new 151 // current time. 152 await waitForNextFrame(); 153 animation.play(); 154 155 await animation.ready; 156 animation.currentTime = CSSNumericValue.parse("33.3%"); 157 158 assert_percents_equal(animation.currentTime, 33.3, 159 "Animation current time should be equal to the set value." 160 ); 161 162 // Cancel the animation and play it again, check that current time has reset 163 // to scroll offset based current time. 164 animation.cancel(); 165 animation.play(); 166 await animation.ready; 167 168 assert_percents_equal(animation.currentTime, animation.timeline.currentTime, 169 "Animation current time should return to a value matching its" + 170 " timeline current time after animation is cancelled and played again." 171 ); 172 }, 'Setting animation.currentTime then restarting the animation should' + 173 ' reset the current time.'); 174 175 promise_test(async t => { 176 const animation = createScrollLinkedAnimation(t); 177 const scroller = animation.timeline.source; 178 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 179 scroller.scrollTop = 0.25 * maxScroll; 180 // Wait for new animation frame which allows the timeline to compute new 181 // current time. 182 await waitForNextFrame(); 183 animation.play(); 184 185 await animation.ready; 186 const originalCurrentTime = animation.currentTime.value; 187 188 // Set the current time to something other than where the scroll offset. 189 animation.currentTime = CSSNumericValue.parse("50%"); 190 191 // Setting current time is internally setting the start time to 192 // scrollTimeline.currentTime - newAnimationCurrentTime. 193 // Which results in current time of (timeline.currentTime - start_time). 194 // This behavior puts the animation in a strange "out of sync" state between 195 // the scroller and the animation effect, this is currently expected 196 // behavior. 197 198 const expectedStartTime = originalCurrentTime - animation.currentTime.value; 199 assert_percents_equal(animation.startTime, expectedStartTime, 200 "Animation current time should be updated when setting the current time" + 201 " to a time within the range of the animation."); 202 203 scroller.scrollTop = 0.7 * maxScroll; 204 // Wait for new animation frame which allows the timeline to compute new 205 // current time. 206 await waitForNextFrame(); 207 208 assert_percents_equal(animation.startTime, expectedStartTime, 209 "Animation start time should remain unchanged when the scroller changes" + 210 " position." 211 ); 212 assert_percents_equal(animation.currentTime, 213 animation.timeline.currentTime.value - animation.startTime.value, 214 "Animation current time should return to a value equal to" + 215 " (timeline.currentTime - animation.startTime) after timeline scroll" + 216 " source has been scrolled." 217 ); 218 }, 'Set Animation current time then scroll.'); 219 220 promise_test(async t => { 221 const animation = createScrollLinkedAnimation(t); 222 const scroller = animation.timeline.source; 223 224 // Wait for new animation frame which allows the timeline to compute new 225 // current time. 226 await waitForNextFrame(); 227 animation.play(); 228 await animation.ready; 229 230 // Make the timeline inactive. 231 await runAndWaitForFrameUpdate(() => { 232 scroller.style.overflow = 'visible'; 233 }); 234 235 assert_equals(animation.currentTime, null, 236 'Current time is unresolved when the timeline is inactive.'); 237 238 animation.currentTime = CSSNumericValue.parse("30%"); 239 assert_percents_equal(animation.currentTime, 30, 240 'Animation current time should be equal to the set value.'); 241 assert_equals(animation.playState, 'paused', 242 'Animation play state is \'paused\' when current time is set and ' + 243 'timeline is inactive.'); 244 }, 'Animation current time and play state are correct when current time is ' + 245 'set while the timeline is inactive.'); 246 247 promise_test(async t => { 248 const animation = createScrollLinkedAnimation(t); 249 const scroller = animation.timeline.source; 250 251 // Wait for new animation frame which allows the timeline to compute new 252 // current time. 253 await waitForNextFrame(); 254 animation.play(); 255 await animation.ready; 256 257 // Make the timeline inactive. 258 await runAndWaitForFrameUpdate(() => { 259 scroller.style.overflow = 'visible'; 260 }); 261 262 assert_equals(animation.timeline.currentTime, null, 263 'Current time is unresolved when the timeline is inactive.'); 264 265 animation.currentTime = CSSNumericValue.parse("30%"); 266 assert_percents_equal(animation.currentTime, 30, 267 'Animation current time should be equal to the set value.'); 268 assert_equals(animation.playState, 'paused', 269 'Animation play state is \'paused\' when current time is set and ' + 270 'timeline is inactive.'); 271 272 // Make the timeline active. 273 await runAndWaitForFrameUpdate(() => { 274 scroller.style.overflow = 'auto'; 275 }); 276 277 assert_percents_equal(animation.timeline.currentTime, 0, 278 'Current time is resolved when the timeline is active.'); 279 assert_percents_equal(animation.currentTime, 30, 280 'Animation current time holds the set value.'); 281 assert_equals(animation.playState, 'paused', 282 'Animation holds \'paused\' state.'); 283 }, 'Animation current time set while the timeline is inactive holds when the ' + 284 'timeline becomes active again.'); 285 </script> 286 </body>