update-playback-rate.html (5814B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>Seamlessly updating the playback rate of an animation</title> 4 <link rel="help" 5 href="https://drafts.csswg.org/web-animations-1/#seamlessly-updating-the-playback-rate-of-an-animation"> 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 animation.currentTime = CSSNumericValue.parse("50%"); 33 34 animation.updatePlaybackRate(0.5); 35 await animation.ready; 36 assert_percents_equal(animation.currentTime, 50, 37 'Reducing the playback rate should not change the ' + 38 'current time of a playing animation'); 39 40 animation.updatePlaybackRate(2); 41 await animation.ready; 42 assert_percents_equal(animation.currentTime, 50, 43 'Increasing the playback rate should not change the ' + 44 'current time of a playing animation'); 45 }, 'Updating the playback rate maintains the current time'); 46 47 promise_test(async t => { 48 const animation = createScrollLinkedAnimation(t); 49 // Wait for new animation frame which allows the timeline to compute new 50 // current time. 51 await waitForNextFrame(); 52 animation.play(); 53 await animation.ready; 54 55 assert_false(animation.pending); 56 animation.updatePlaybackRate(2); 57 assert_true(animation.pending); 58 }, 'Updating the playback rate while running makes the animation pending'); 59 60 promise_test(async t => { 61 const animation = createScrollLinkedAnimation(t); 62 // Wait for new animation frame which allows the timeline to compute new 63 // current time. 64 await waitForNextFrame(); 65 animation.play(); 66 animation.currentTime = CSSNumericValue.parse("50%"); 67 assert_true(animation.pending); 68 69 animation.updatePlaybackRate(0.5); 70 71 // Check that the hold time is updated as expected 72 assert_percents_equal(animation.currentTime, 50); 73 74 await animation.ready; 75 76 // As above, check that the currentTime is not calculated by simply 77 // substituting in the updated playbackRate without updating the startTime. 78 assert_percents_equal(animation.currentTime, 50, 79 'Reducing the playback rate should not change the ' + 80 'current time of a play-pending animation'); 81 }, 'Updating the playback rate on a play-pending animation maintains the ' + 82 'current time'); 83 84 promise_test(async t => { 85 const animation = createScrollLinkedAnimation(t); 86 // Wait for new animation frame which allows the timeline to compute new 87 // current time. 88 await waitForNextFrame(); 89 animation.play(); 90 animation.currentTime = CSSNumericValue.parse("50%"); 91 await animation.ready; 92 93 animation.pause(); 94 animation.updatePlaybackRate(0.5); 95 96 assert_percents_equal(animation.currentTime, 50); 97 }, 'Updating the playback rate on a pause-pending animation maintains the ' + 98 'current time'); 99 100 promise_test(async t => { 101 const animation = createScrollLinkedAnimation(t); 102 // Wait for new animation frame which allows the timeline to compute new 103 // current time. 104 await waitForNextFrame(); 105 animation.play(); 106 107 animation.updatePlaybackRate(2); 108 animation.updatePlaybackRate(3); 109 animation.updatePlaybackRate(4); 110 111 assert_equals(animation.playbackRate, 1); 112 await animation.ready; 113 114 assert_equals(animation.playbackRate, 4); 115 }, 'If a pending playback rate is set multiple times, the latest wins'); 116 117 promise_test(async t => { 118 const animation = createScrollLinkedAnimation(t); 119 // Wait for new animation frame which allows the timeline to compute new 120 // current time. 121 await waitForNextFrame(); 122 animation.play(); 123 animation.cancel(); 124 125 animation.updatePlaybackRate(2); 126 assert_equals(animation.playbackRate, 2); 127 assert_false(animation.pending); 128 }, 'In the idle state, the playback rate is applied immediately'); 129 130 promise_test(async t => { 131 const animation = createScrollLinkedAnimation(t); 132 // Wait for new animation frame which allows the timeline to compute new 133 // current time. 134 await waitForNextFrame(); 135 animation.pause(); 136 await animation.ready; 137 138 animation.updatePlaybackRate(2); 139 assert_equals(animation.playbackRate, 2); 140 assert_false(animation.pending); 141 }, 'In the paused state, the playback rate is applied immediately'); 142 143 promise_test(async t => { 144 const animation = createScrollLinkedAnimation(t); 145 // Wait for new animation frame which allows the timeline to compute new 146 // current time. 147 await waitForNextFrame(); 148 animation.play(); 149 animation.finish(); 150 assert_percents_equal(animation.currentTime, 100); 151 assert_false(animation.pending); 152 153 animation.updatePlaybackRate(2); 154 assert_equals(animation.playbackRate, 2); 155 assert_percents_equal(animation.currentTime, 100); 156 assert_false(animation.pending); 157 }, 'Updating the playback rate on a finished animation maintains the current ' + 158 'time'); 159 160 promise_test(async t => { 161 const animation = createScrollLinkedAnimation(t); 162 // Wait for new animation frame which allows the timeline to compute new 163 // current time. 164 await waitForNextFrame(); 165 animation.play(); 166 animation.finish(); 167 assert_percents_equal(animation.currentTime, 100); 168 assert_false(animation.pending); 169 170 animation.updatePlaybackRate(0); 171 assert_equals(animation.playbackRate, 0); 172 assert_percents_equal(animation.currentTime, 100); 173 assert_false(animation.pending); 174 }, 'Updating the playback rate to zero on a finished animation maintains the ' + 175 'current time'); 176 177 </script> 178 </body>