pause-animation.html (6478B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>Pausing an animation</title> 4 <link rel="help" 5 href="https://drafts.csswg.org/web-animations/#pausing-an-animation-section"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="/web-animations/testcommon.js"></script> 9 <script src="testcommon.js"></script> 10 <style> 11 .scroller { 12 overflow: auto; 13 height: 100px; 14 width: 100px; 15 will-change: transform; 16 } 17 18 .contents { 19 height: 1000px; 20 width: 100%; 21 } 22 </style> 23 <body> 24 <script> 25 'use strict'; 26 27 promise_test(async t => { 28 const animation = createScrollLinkedAnimation(t); 29 animation.play(); 30 await animation.ready; 31 32 const startTimeBeforePausing = animation.startTime; 33 34 animation.pause(); 35 assert_percents_equal(animation.startTime, startTimeBeforePausing, 36 'The start time does not change when pausing-pending'); 37 38 await animation.ready; 39 40 assert_equals(animation.startTime, null, 41 'The start time is unresolved when paused'); 42 }, 'Pausing clears the start time'); 43 44 promise_test(async t => { 45 const animation = createScrollLinkedAnimation(t); 46 animation.play(); 47 const promise = animation.ready; 48 animation.pause(); 49 50 const promiseResult = await promise; 51 52 assert_equals(promiseResult, animation); 53 assert_equals(animation.ready, promise); 54 assert_false(animation.pending, 'No longer pause-pending'); 55 }, 'A pending ready promise should be resolved and not replaced when the' 56 + ' animation is paused'); 57 58 promise_test(async t => { 59 const animation = createScrollLinkedAnimation(t); 60 animation.play(); 61 // Let animation start roughly half-way through 62 animation.currentTime = CSSNumericValue.parse("50%"); 63 await animation.ready; 64 65 // Go pause-pending and also set a pending playback rate 66 animation.pause(); 67 animation.updatePlaybackRate(0.5); 68 69 await animation.ready; 70 // If the current time was updated using the new playback rate it will jump 71 // back to 25% but if we correctly used the old playback rate the current time 72 // will be > 50%. 73 assert_percents_equal(animation.currentTime, 50); 74 }, 'A pause-pending animation maintains the current time when applying a' 75 + ' pending playback rate'); 76 77 promise_test(async t => { 78 // This test does not cover a specific step in the algorithm but serves as a 79 // high-level sanity check that pausing does, in fact, freeze the current 80 // time. 81 const animation = createScrollLinkedAnimation(t); 82 const scroller = animation.timeline.source; 83 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 84 animation.play(); 85 await animation.ready; 86 87 animation.pause(); 88 await animation.ready; 89 90 const currentTimeAfterPausing = animation.currentTime; 91 92 await runAndWaitForFrameUpdate(() => { 93 scroller.scrollTop = 0.2 * maxScroll; 94 }); 95 assert_percents_equal(animation.timeline.currentTime, 20, 96 'Sanity check timeline time changed'); 97 98 assert_percents_equal(animation.currentTime, currentTimeAfterPausing, 99 'Animation.currentTime is unchanged after pausing'); 100 }, 'The animation\'s current time remains fixed after pausing'); 101 102 promise_test(async t => { 103 const animation = createScrollLinkedAnimation(t); 104 animation.play(); 105 106 const originalReadyPromise = animation.ready; 107 animation.cancel(); 108 assert_equals(animation.startTime, null); 109 assert_equals(animation.currentTime, null); 110 111 const readyPromise = animation.ready; 112 assert_not_equals(originalReadyPromise, readyPromise, 113 'Canceling an animation should create a new ready promise'); 114 115 animation.pause(); 116 assert_equals(animation.playState, 'paused', 117 'Pausing a canceled animation should update the play state'); 118 assert_true(animation.pending, 'animation should be pause-pending'); 119 await animation.ready; 120 assert_false(animation.pending, 121 'animation should no longer be pause-pending'); 122 assert_equals(animation.startTime, null, 'start time should be unresolved'); 123 assert_percents_equal(animation.currentTime, 0, 124 'current time should be set to zero'); 125 }, 'Pausing a canceled animation sets the current time'); 126 127 promise_test(async t => { 128 const animation = createScrollLinkedAnimation(t); 129 const scroller = animation.timeline.source; 130 // Wait for new animation frame which allows the timeline to compute new 131 // current time. 132 await runAndWaitForFrameUpdate(() => { 133 // Make the scroll timeline inactive. 134 scroller.style.overflow = 'visible'; 135 }); 136 assert_equals(animation.timeline.currentTime, null, 137 'Sanity check the timeline is inactive.'); 138 // Pause the animation when the timeline is inactive. 139 animation.pause(); 140 assert_equals(animation.currentTime, null, 141 'The current time is null when the timeline is inactive.'); 142 assert_equals(animation.startTime, null, 143 'The start time is null in Pending state.'); 144 await waitForNextFrame(); 145 assert_true(animation.pending, 146 'Animation has pause pending task while the timeline is inactive.'); 147 assert_equals(animation.playState, 'paused', 148 `State is 'paused' in Pending state.`); 149 }, `Pause pending task doesn't run when the timeline is inactive.`); 150 151 promise_test(async t => { 152 const animation = createScrollLinkedAnimation(t); 153 const scroller = animation.timeline.source; 154 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 155 scroller.scrollTop = 0.2 * maxScroll; 156 // Wait for new animation frame which allows the timeline to compute new 157 // current time. 158 await runAndWaitForFrameUpdate(() => { 159 // Make the scroll timeline inactive. 160 scroller.style.overflow = 'visible'; 161 }); 162 assert_equals(animation.timeline.currentTime, null, 163 'Sanity check the timeline is inactive.'); 164 // Play the animation when the timeline is inactive. 165 animation.pause(); 166 167 // Make the scroll timeline active. 168 scroller.style.overflow = 'auto'; 169 await animation.ready; 170 // Ready promise is resolved as a result of the timeline becoming active. 171 assert_percents_equal(animation.currentTime, 20, 172 'Animation current time is resolved when the animation is ready.'); 173 assert_equals(animation.startTime, null, 174 'Animation start time is unresolved when the animation is ready.'); 175 }, 'Animation start and current times are correct if scroll timeline is ' + 176 'activated after animation.pause call.'); 177 178 </script> 179 </body>