scroll-animation-effect-fill-modes.tentative.html (4381B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <title>Verify applied effect output for all fill modes in all timeline states: before start, at start, in range, at end, after end while using various effect delay values</title> 4 <meta name="timeout" content="long"> 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: hidden; 12 height: 200px; 13 width: 200px; 14 } 15 .contents { 16 /* Make scroll range 1000 to simplify the math and avoid rounding errors */ 17 height: 1200px; 18 width: 100%; 19 } 20 </style> 21 <div id="log"></div> 22 <script> 23 'use strict'; 24 25 test(t => { 26 const effect = new KeyframeEffect(createDiv(t), { opacity: [0.3, 0.7] }); 27 const animation = new Animation(effect, createScrollTimeline(t)); 28 29 assert_equals(effect.getTiming().fill, "auto"); 30 assert_equals(effect.getComputedTiming().fill, "none"); 31 }, "Scroll based animation effect fill mode should return 'auto' for" + 32 " getTiming() and should return 'none' for getComputedTiming().") 33 34 /* All interesting transitions: 35 before start delay 36 at start delay 37 within active phase 38 at effect end 39 after effect end 40 41 test_case data structure: 42 fill_mode: { 43 scroll_percentage: ["state description", expected applied effect value] 44 } 45 */ 46 const test_cases = { 47 "none": { 48 0.10: ["before start delay", 1], 49 0.25: ["at start delay", 0.3], 50 0.50: ["at midpoint", 0.5], 51 0.75: ["at effect end", 1], 52 0.90: ["after effect end", 1] 53 }, 54 "backwards": { 55 0.10: ["before start delay", 0.3], 56 0.25: ["at start delay", 0.3], 57 0.50: ["at midpoint", 0.5], 58 0.75: ["at effect end", 1], 59 0.90: ["after effect end", 1] 60 }, 61 "forwards": { 62 0.10: ["before timeline start", 1], 63 0.25: ["at timeline start", 0.3], 64 0.50: ["in timeline range", 0.5], 65 0.75: ["at timeline end", 0.7], 66 0.90: ["after timeline end", 0.7] 67 }, 68 "both": { 69 0.10: ["before timeline start", 0.3], 70 0.25: ["at timeline start", 0.3], 71 0.50: ["in timeline range", 0.5], 72 0.75: ["at timeline end", 0.7], 73 0.90: ["after timeline end", 0.7] 74 }, 75 "auto": { 76 0.10: ["before timeline start", 1], 77 0.25: ["at timeline start", 0.3], 78 0.50: ["in timeline range", 0.5], 79 0.75: ["at timeline end", 1], 80 0.90: ["after timeline end", 1] 81 } 82 } 83 84 for (const fill_mode in test_cases) { 85 const scroll_percents = test_cases[fill_mode] 86 87 for (const scroll_percentage in scroll_percents) { 88 const expectation = scroll_percents[scroll_percentage]; 89 90 const [test_name, expected_value] = expectation; 91 92 const description = 93 `Applied effect value ${test_name} with fill: ${fill_mode}` 94 promise_test( 95 create_scroll_timeline_fill_test( 96 fill_mode, scroll_percentage, expected_value), 97 description); 98 } 99 } 100 101 function create_scroll_timeline_fill_test( 102 fill_mode, scroll_percentage, expected){ 103 return async t => { 104 const target = createDiv(t); 105 106 const timeline = createScrollTimeline(t); 107 const effect = 108 new KeyframeEffect(target, 109 { opacity: [0.3, 0.7] }, 110 { 111 fill: fill_mode, 112 /* Animation times normalized to fill scroll 113 range */ 114 duration: 2000, 115 delay: 1000, 116 endDelay: 1000 117 }); 118 const animation = new Animation(effect, timeline); 119 const scroller = timeline.source; 120 const maxScroll = scroller.scrollHeight - scroller.clientHeight; 121 122 animation.play(); 123 124 await animation.ready; 125 126 scroller.scrollTop = scroll_percentage * maxScroll; 127 128 // Wait for new animation frame which allows the timeline to compute 129 // new current time. 130 await waitForNextFrame(); 131 await waitForNextFrame(); 132 133 assert_equals(parseFloat(window.getComputedStyle(target).opacity), 134 expected, 135 "animation effect applied property value"); 136 } 137 } 138 </script>