CSSAnimation-pausing.tentative.html (7386B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>Pausing a CSSAnimation</title> 4 <link rel="help" 5 href="https://drafts.csswg.org/css-animations-2/#animation-play-state"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="support/testcommon.js"></script> 9 <style> 10 @keyframes anim { 11 0% { margin-left: 0px } 12 100% { margin-left: 10000px } 13 } 14 </style> 15 <div id="log"></div> 16 <script> 17 'use strict'; 18 19 promise_test(async t => { 20 const div = addDiv(t); 21 div.style.animation = 'anim 1000s paused'; 22 23 const animation = div.getAnimations()[0]; 24 animation.play(); 25 26 await animation.ready; 27 await waitForNextFrame(); 28 29 assert_equals( 30 animation.playState, 31 'running', 32 'Play state is running after calling play()' 33 ); 34 35 // Flip the animation-play-state back and forth to check it has no effect 36 37 div.style.animationPlayState = 'running'; 38 getComputedStyle(div).animationPlayState; 39 div.style.animationPlayState = 'paused'; 40 getComputedStyle(div).animationPlayState; 41 42 assert_equals( 43 animation.playState, 44 'running', 45 'Should still be running even after flipping the animation-play-state' 46 ); 47 }, 'play() overrides animation-play-state'); 48 49 promise_test(async t => { 50 const div = addDiv(t); 51 div.style.animation = 'anim 100s infinite paused'; 52 53 const animation = div.getAnimations()[0]; 54 animation.playbackRate = -1; 55 animation.currentTime = -1; 56 57 assert_throws_dom('InvalidStateError', () => { 58 animation.play(); 59 }, 'Trying to play a reversed infinite animation should throw'); 60 61 assert_equals( 62 animation.playState, 63 'paused', 64 'Animation should still be paused' 65 ); 66 67 animation.playbackRate = 1; 68 div.style.animationPlayState = 'running'; 69 70 assert_equals( 71 animation.playState, 72 'running', 73 'Changing the animation-play-state should play the animation' 74 ); 75 }, 'play() does NOT override the animation-play-state if there was an error'); 76 77 promise_test(async t => { 78 const div = addDiv(t); 79 div.style.animation = 'anim 1000s paused'; 80 81 const animation = div.getAnimations()[0]; 82 animation.pause(); 83 84 div.style.animationPlayState = 'running'; 85 getComputedStyle(div).animationPlayState; 86 87 await animation.ready; 88 await waitForNextFrame(); 89 90 assert_equals(animation.playState, 'paused', 'playState is paused '); 91 92 // Flip the animation-play-state back and forth to check it has no effect 93 94 div.style.animationPlayState = 'paused'; 95 getComputedStyle(div).animationPlayState; 96 div.style.animationPlayState = 'running'; 97 getComputedStyle(div).animationPlayState; 98 99 assert_equals( 100 animation.playState, 101 'paused', 102 'Should still be paused even after flipping the animation-play-state' 103 ); 104 }, 'pause() overrides animation-play-state'); 105 106 promise_test(async t => { 107 const div = addDiv(t); 108 div.style.animation = 'anim 100s paused'; 109 110 const animation = div.getAnimations()[0]; 111 animation.reverse(); 112 113 assert_equals( 114 animation.playState, 115 'running', 116 'Play state is running after calling reverse()' 117 ); 118 119 // Flip the animation-play-state back and forth to check it has no effect 120 121 div.style.animationPlayState = 'running'; 122 getComputedStyle(div).animationPlayState; 123 div.style.animationPlayState = 'paused'; 124 getComputedStyle(div).animationPlayState; 125 126 assert_equals( 127 animation.playState, 128 'running', 129 'Should still be running even after flipping the animation-play-state' 130 ); 131 }, 'reverse() overrides animation-play-state when it starts playing the' 132 + ' animation'); 133 134 promise_test(async t => { 135 const div = addDiv(t); 136 div.style.animation = 'anim 100s'; 137 138 const animation = div.getAnimations()[0]; 139 animation.reverse(); 140 141 assert_equals( 142 animation.playState, 143 'running', 144 'Play state is running after calling reverse()' 145 ); 146 147 div.style.animationPlayState = 'paused'; 148 getComputedStyle(div).animationPlayState; 149 150 assert_equals( 151 animation.playState, 152 'paused', 153 'Should be paused after changing the animation-play-state' 154 ); 155 }, 'reverse() does NOT override animation-play-state if the animation is' 156 + ' already running'); 157 158 promise_test(async t => { 159 const div = addDiv(t); 160 div.style.animation = 'anim 100s'; 161 162 const animation = div.getAnimations()[0]; 163 animation.startTime = null; 164 165 assert_equals( 166 animation.playState, 167 'paused', 168 'Play state is paused after setting the start time to null' 169 ); 170 171 // Flip the animation-play-state back and forth to check it has no effect 172 173 div.style.animationPlayState = 'paused'; 174 getComputedStyle(div).animationPlayState; 175 div.style.animationPlayState = 'running'; 176 getComputedStyle(div).animationPlayState; 177 178 assert_equals( 179 animation.playState, 180 'paused', 181 'Should still be paused even after flipping the animation-play-state' 182 ); 183 }, 'Setting the startTime to null overrides animation-play-state if the' 184 + ' animation is already running'); 185 186 promise_test(async t => { 187 const div = addDiv(t); 188 div.style.animation = 'anim 100s paused'; 189 190 const animation = div.getAnimations()[0]; 191 animation.startTime = document.timeline.currentTime; 192 193 assert_equals( 194 animation.playState, 195 'running', 196 'Play state is running after setting the start time to non-null' 197 ); 198 199 // Flip the animation-play-state back and forth to check it has no effect 200 201 div.style.animationPlayState = 'running'; 202 getComputedStyle(div).animationPlayState; 203 div.style.animationPlayState = 'paused'; 204 getComputedStyle(div).animationPlayState; 205 206 assert_equals( 207 animation.playState, 208 'running', 209 'Should still be running even after flipping the animation-play-state' 210 ); 211 }, 'Setting the startTime to non-null overrides animation-play-state if the' 212 + ' animation is paused'); 213 214 promise_test(async t => { 215 const div = addDiv(t); 216 div.style.animation = 'anim 100s'; 217 218 const animation = div.getAnimations()[0]; 219 animation.startTime = document.timeline.currentTime; 220 221 div.style.animationPlayState = 'paused'; 222 getComputedStyle(div).animationPlayState; 223 224 assert_equals( 225 animation.playState, 226 'paused', 227 'Should be paused after changing the animation-play-state' 228 ); 229 }, 'Setting the startTime to non-null does NOT override the' 230 + ' animation-play-state if the animation is already running'); 231 232 promise_test(async t => { 233 const div = addDiv(t, { style: 'animation: anim 1000s' }); 234 const animation = div.getAnimations()[0]; 235 let readyPromiseRun = false; 236 237 await animation.ready; 238 239 div.style.animationPlayState = 'paused'; 240 assert_true(animation.pending && animation.playState === 'paused', 241 'Animation is pause-pending'); 242 243 // Set current time 244 animation.currentTime = 5 * MS_PER_SEC; 245 assert_equals(animation.playState, 'paused', 246 'Animation is paused immediately after setting currentTime'); 247 assert_equals(animation.startTime, null, 248 'Animation startTime is unresolved immediately after ' + 249 'setting currentTime'); 250 assert_equals(animation.currentTime, 5 * MS_PER_SEC, 251 'Animation currentTime does not change when forcing a ' + 252 'pause operation to complete'); 253 254 // The ready promise should now be resolved. If it's not then test will 255 // probably time out before anything else happens that causes it to resolve. 256 await animation.ready; 257 }, 'Setting the current time completes a pending pause'); 258 259 </script>