view-timeline-animation.html (8998B)
1 <!DOCTYPE html> 2 <title>Animations using view-timeline</title> 3 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1"> 4 <link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#view-timelines-named"> 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="support/testcommon.js"></script> 9 <style> 10 @keyframes anim { 11 from { z-index: 0; } 12 to { z-index: 100; } 13 } 14 .vertical-scroller { 15 overflow: auto; 16 width: 100px; 17 height: 100px; 18 } 19 .vertical-scroller > div { 20 height: 50px; 21 z-index: -1; 22 } 23 .horizontal-scroller { 24 overflow: auto; 25 width: 100px; 26 height: 100px; 27 writing-mode: vertical-lr; 28 } 29 .horizontal-scroller > div { 30 width: 50px; 31 z-index: -1; 32 } 33 </style> 34 <main id=main></main> 35 <script> 36 setup(assert_implements_animation_timeline); 37 38 function inflate(t, template) { 39 t.add_cleanup(() => main.replaceChildren()); 40 main.append(template.content.cloneNode(true)); 41 } 42 async function scrollTop(e, value) { 43 e.scrollTop = value; 44 await waitForNextFrame(); 45 } 46 async function scrollLeft(e, value) { 47 e.scrollLeft = value; 48 await waitForNextFrame(); 49 } 50 </script> 51 52 <template id=default_view_timeline> 53 <style> 54 #target { 55 view-timeline: --t1; 56 animation: anim 1s linear forwards; 57 animation-timeline: --t1; 58 } 59 </style> 60 <div id=scroller class=vertical-scroller> 61 <div></div> <!-- [0px, 50px] --> 62 <div></div> <!-- [50px, 100px] --> 63 <div></div> <!-- [100px, 150px] --> 64 <div id=target></div> <!-- [150px, 200px] --> 65 <div></div> <!-- [200px, 250px] --> 66 <div></div> <!-- [250px, 300px] --> 67 <div></div> <!-- [300px, 350px] --> 68 </div> 69 </template> 70 <script> 71 promise_test(async (t) => { 72 inflate(t, default_view_timeline); 73 assert_equals(getComputedStyle(target).zIndex, '-1'); 74 await scrollTop(scroller, 25); 75 assert_equals(getComputedStyle(target).zIndex, '-1'); 76 await scrollTop(scroller, 50); // 0% (enter 0%) 77 assert_equals(getComputedStyle(target).zIndex, '0'); 78 await scrollTop(scroller, 125); // 50% 79 assert_equals(getComputedStyle(target).zIndex, '50'); 80 await scrollTop(scroller, 200); // 100% (exit 100%) 81 assert_equals(getComputedStyle(target).zIndex, '100'); 82 await scrollTop(scroller, 201); // now over the 100% scroll offset, but "fill: forwards" lets the animation apply. 83 assert_equals(getComputedStyle(target).zIndex, '100'); 84 document.getAnimations()[0].effect.updateTiming( { fill: 'none' }); 85 assert_equals(getComputedStyle(target).zIndex, '-1'); 86 await scrollTop(scroller, 200); // now back to the 100% scroll offset. 87 assert_equals(getComputedStyle(target).zIndex, '100'); 88 }, 'Default view-timeline'); 89 </script> 90 91 <template id=horizontal_timeline> 92 <style> 93 #target { 94 view-timeline: --t1 x; 95 animation: anim 1s linear forwards; 96 animation-timeline: --t1; 97 } 98 </style> 99 <div id=scroller class=horizontal-scroller> 100 <div></div> <!-- [0px, 50px] --> 101 <div></div> <!-- [50px, 100px] --> 102 <div></div> <!-- [100px, 150px] --> 103 <div id=target></div> <!-- [150px, 200px] --> 104 <div></div> <!-- [200px, 250px] --> 105 <div></div> <!-- [250px, 300px] --> 106 <div></div> <!-- [300px, 350px] --> 107 </div> 108 </template> 109 <script> 110 promise_test(async (t) => { 111 inflate(t, horizontal_timeline); 112 assert_equals(getComputedStyle(target).zIndex, '-1'); 113 await scrollLeft(scroller, 25); 114 assert_equals(getComputedStyle(target).zIndex, '-1'); 115 await scrollLeft(scroller, 50); // 0% (enter 0%) 116 assert_equals(getComputedStyle(target).zIndex, '0'); 117 await scrollLeft(scroller, 125); // 50% 118 assert_equals(getComputedStyle(target).zIndex, '50'); 119 await scrollLeft(scroller, 200); // 100% (exit 100%) 120 assert_equals(getComputedStyle(target).zIndex, '100'); 121 await scrollLeft(scroller, 201); // now over the 100% scroll offset, but "fill: forwards" lets the animation apply. 122 assert_equals(getComputedStyle(target).zIndex, '100'); 123 document.getAnimations()[0].effect.updateTiming( { fill: 'none' }); 124 assert_equals(getComputedStyle(target).zIndex, '-1'); 125 await scrollLeft(scroller, 200); // now back to the 100% scroll offset. 126 assert_equals(getComputedStyle(target).zIndex, '100'); 127 }, 'Horizontal view-timeline'); 128 </script> 129 130 <template id=multiple_timelines> 131 <style> 132 #timelines { 133 view-timeline: --tv y, --th x; 134 background-color: red; 135 } 136 #scroller { 137 width: 100px; 138 height: 100px; 139 overflow: hidden; 140 display: grid; 141 grid-template-columns: 50px 50px 50px 50px 50px 50px 50px; 142 grid-template-row: 50px 50px 50px 50px 50px 50px 50px; 143 timeline-scope: --tv, --th; 144 } 145 #scroller > div { 146 z-index: -1; 147 width: 50px; 148 height: 50px; 149 } 150 #target_v { 151 animation: anim 1s linear forwards; 152 animation-timeline: --tv; 153 } 154 #target_h { 155 animation: anim 1s linear forwards; 156 animation-timeline: --th; 157 } 158 </style> 159 <div id=scroller> 160 <!-- Created dynamically --> 161 </div> 162 </template> 163 <script> 164 promise_test(async (t) => { 165 inflate(t, multiple_timelines); 166 167 // Create a 350px x 350px grid (7x7 items of 50x50px each), with the 168 // timelines at item [3,3], an element attached to the horizontal timeline 169 // at [4,3], and an element attached to the vertical timeline at [3,4]. 170 171 // x x x x x x x 172 // x x x x x x x 173 // x x x x x x x 174 // x x x T H x x 175 // x x x V x x x 176 // x x x x x x x 177 // x x x x x x x 178 // x x x x x x x 179 180 let grid_size = 7; 181 for (let i = 0; i < (grid_size*grid_size); ++i) { 182 let div = document.createElement('div'); 183 if (i == (3 * grid_size + 3)) 184 div.id = 'timelines'; 185 if (i == (3 * grid_size + 4)) 186 div.id = 'target_h'; 187 if (i == (4 * grid_size + 3)) 188 div.id = 'target_v'; 189 scroller.append(div); 190 } 191 192 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 193 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 194 195 // First scroll vertically. 196 await scrollTop(scroller, 25); 197 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 198 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 199 await scrollTop(scroller, 50); // 0% (enter 0%) 200 assert_equals(getComputedStyle(target_v).zIndex, '0'); 201 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 202 await scrollTop(scroller, 125); // 50% 203 assert_equals(getComputedStyle(target_v).zIndex, '50'); 204 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 205 await scrollTop(scroller, 200); // 100% (exit 100%) 206 assert_equals(getComputedStyle(target_v).zIndex, '100'); 207 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 208 await scrollTop(scroller, 201); // now over the 100% scroll offset, but "fill: forwards" lets the animation apply. 209 assert_equals(getComputedStyle(target_v).zIndex, '100'); 210 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 211 document.getElementById('target_v').getAnimations()[0]. 212 effect.updateTiming({ fill: 'none' }); 213 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 214 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 215 216 // Then horizontally. 217 await scrollLeft(scroller, 25); 218 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 219 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 220 await scrollLeft(scroller, 50); // 0% (enter 0%) 221 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 222 assert_equals(getComputedStyle(target_h).zIndex, '0'); 223 await scrollLeft(scroller, 125); // 50% 224 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 225 assert_equals(getComputedStyle(target_h).zIndex, '50'); 226 await scrollLeft(scroller, 200); // 100% (exit 100%) 227 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 228 assert_equals(getComputedStyle(target_h).zIndex, '100'); 229 await scrollLeft(scroller, 201); // now over the 100% scroll offset, but "fill: forwards" lets the animation apply. 230 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 231 assert_equals(getComputedStyle(target_h).zIndex, '100'); 232 document.getElementById('target_h').getAnimations()[0]. 233 effect.updateTiming({ fill: 'none' }); 234 assert_equals(getComputedStyle(target_v).zIndex, '-1'); 235 assert_equals(getComputedStyle(target_h).zIndex, '-1'); 236 237 await scrollTop(scroller, 200); // now back to the 100% scroll offset. 238 await scrollLeft(scroller, 200); // now back to the 100% scroll offset. 239 assert_equals(getComputedStyle(target_v).zIndex, '100'); 240 assert_equals(getComputedStyle(target_h).zIndex, '100'); 241 }, 'Multiple view-timelines on the same element'); 242 </script>