CSSAnimation-canceling.tentative.html (6708B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>Canceling a CSS animation</title> 4 <!-- TODO: Add a more specific link for this once it is specified. --> 5 <link rel="help" href="https://drafts.csswg.org/css-animations-2/"> 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 translateAnim { 11 to { transform: translate(100px) } 12 } 13 @keyframes marginLeftAnim { 14 to { margin-left: 100px } 15 } 16 @keyframes marginLeftAnim100To200 { 17 from { margin-left: 100px } 18 to { margin-left: 200px } 19 } 20 </style> 21 <div id="log"></div> 22 <script> 23 'use strict'; 24 25 promise_test(async t => { 26 const div = addDiv(t, { style: 'animation: translateAnim 100s' }); 27 const animation = div.getAnimations()[0]; 28 29 await animation.ready; 30 31 assert_not_equals(getComputedStyle(div).transform, 'none', 32 'transform style is animated before canceling'); 33 animation.cancel(); 34 assert_equals(getComputedStyle(div).transform, 'none', 35 'transform style is no longer animated after canceling'); 36 }, 'Animated style is cleared after canceling a running CSS animation'); 37 38 promise_test(async t => { 39 const div = addDiv(t, { style: 'animation: translateAnim 100s forwards' }); 40 const animation = div.getAnimations()[0]; 41 animation.finish(); 42 43 await animation.ready; 44 45 assert_not_equals(getComputedStyle(div).transform, 'none', 46 'transform style is filling before canceling'); 47 animation.cancel(); 48 assert_equals(getComputedStyle(div).transform, 'none', 49 'fill style is cleared after canceling'); 50 }, 'Animated style is cleared after canceling a filling CSS animation'); 51 52 test(t => { 53 const div = addDiv(t, { style: 'animation: marginLeftAnim 100s linear' }); 54 const animation = div.getAnimations()[0]; 55 animation.cancel(); 56 57 assert_equals(getComputedStyle(div).marginLeft, '0px', 58 'margin-left style is not animated after canceling'); 59 60 animation.currentTime = 50 * 1000; 61 assert_equals(getComputedStyle(div).marginLeft, '50px', 62 'margin-left style is updated when canceled animation is' 63 + ' seeked'); 64 }, 'After canceling an animation, it can still be seeked'); 65 66 promise_test(async t => { 67 const div = 68 addDiv(t, { style: 'animation: marginLeftAnim100To200 100s linear' }); 69 const animation = div.getAnimations()[0]; 70 71 await animation.ready; 72 73 animation.cancel(); 74 assert_equals(getComputedStyle(div).marginLeft, '0px', 75 'margin-left style is not animated after canceling'); 76 animation.play(); 77 assert_equals(getComputedStyle(div).marginLeft, '100px', 78 'margin-left style is animated after re-starting animation'); 79 80 await animation.ready; 81 82 assert_equals(animation.playState, 'running', 83 'Animation succeeds in running after being re-started'); 84 }, 'After canceling an animation, it can still be re-used'); 85 86 test(t => { 87 const div = 88 addDiv(t, { style: 'animation: marginLeftAnim100To200 100s linear' }); 89 const animation = div.getAnimations()[0]; 90 animation.cancel(); 91 assert_equals(getComputedStyle(div).marginLeft, '0px', 92 'margin-left style is not animated after canceling'); 93 94 // Trigger a change to some animation properties and check that this 95 // doesn't cause the animation to become live again 96 div.style.animationDuration = '200s'; 97 assert_equals(getComputedStyle(div).marginLeft, '0px', 98 'margin-left style is still not animated after updating' 99 + ' animation-duration'); 100 assert_equals(animation.playState, 'idle', 101 'Animation is still idle after updating animation-duration'); 102 }, 'After canceling an animation, updating animation properties doesn\'t make' 103 + ' it live again'); 104 105 test(t => { 106 const div = 107 addDiv(t, { style: 'animation: marginLeftAnim100To200 100s linear' }); 108 const animation = div.getAnimations()[0]; 109 animation.cancel(); 110 assert_equals(getComputedStyle(div).marginLeft, '0px', 111 'margin-left style is not animated after canceling'); 112 113 // Make some changes to animation-play-state and check that the 114 // animation doesn't become live again. This is because it should be 115 // possible to cancel an animation from script such that all future 116 // changes to style are ignored. 117 118 // Redundant change 119 div.style.animationPlayState = 'running'; 120 assert_equals(animation.playState, 'idle', 121 'Animation is still idle after a redundant change to' 122 + ' animation-play-state'); 123 124 // Pause 125 div.style.animationPlayState = 'paused'; 126 assert_equals(animation.playState, 'idle', 127 'Animation is still idle after setting' 128 + ' animation-play-state: paused'); 129 130 // Play 131 div.style.animationPlayState = 'running'; 132 assert_equals(animation.playState, 'idle', 133 'Animation is still idle after re-setting' 134 + ' animation-play-state: running'); 135 136 }, 'After canceling an animation, updating animation-play-state doesn\'t' 137 + ' make it live again'); 138 139 promise_test(async t => { 140 const div = addDiv(t, { style: 'animation: translateAnim 10s both' }); 141 div.style.marginLeft = '0px'; 142 143 const animation = div.getAnimations()[0]; 144 145 await animation.ready; 146 147 assert_equals(animation.playState, 'running'); 148 149 div.style.animationName = 'none'; 150 flushComputedStyle(div); 151 152 await waitForFrame(); 153 154 assert_equals(animation.playState, 'idle'); 155 assert_equals(getComputedStyle(div).marginLeft, '0px'); 156 }, 'Setting animation-name to \'none\' cancels the animation'); 157 158 promise_test(async t => { 159 const div = addDiv(t, { style: 'animation: translateAnim 10s both' }); 160 const animation = div.getAnimations()[0]; 161 162 await animation.ready; 163 164 assert_equals(animation.playState, 'running'); 165 166 div.style.display = 'none'; 167 168 await waitForFrame(); 169 170 assert_equals(animation.playState, 'idle'); 171 assert_equals(getComputedStyle(div).marginLeft, '0px'); 172 }, 'Setting display:none on an element cancel its animations'); 173 174 promise_test(async t => { 175 const parentDiv = addDiv(t); 176 const childDiv = document.createElement('div'); 177 parentDiv.appendChild(childDiv); 178 179 childDiv.setAttribute('style', 'animation: translateAnim 10s both'); 180 flushComputedStyle(childDiv); 181 182 const animation = childDiv.getAnimations()[0]; 183 184 await animation.ready; 185 186 assert_equals(animation.playState, 'running'); 187 188 parentDiv.style.display = 'none'; 189 await waitForFrame(); 190 191 assert_equals(animation.playState, 'idle'); 192 assert_equals(getComputedStyle(childDiv).marginLeft, '0px'); 193 }, 'Setting display:none on an ancestor element cancels animations on ' + 194 'descendants'); 195 196 </script>