animation-events.html (3041B)
1 <!DOCTYPE html> 2 <html id="top"> 3 <meta charset="utf-8"> 4 <title>View timeline animation events</title> 5 <link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#events"> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script src="/web-animations/testcommon.js"></script> 9 <style type="text/css"> 10 @keyframes anim { 11 from { transform: translateX(0); } 12 to { transform: translateX(100px); } 13 } 14 #target { 15 background: green; 16 height: 100px; 17 width: 100px; 18 margin-bottom: 150vh; 19 animation-timeline: view(); 20 } 21 .animate { 22 animation: anim auto; 23 } 24 </style> 25 <body> 26 <div id="target"></div> 27 </body> 28 <script type="text/javascript"> 29 promise_test(async t => { 30 const target = document.getElementById('target'); 31 32 // Create a timeline and advance to the next frame to ensure that the 33 // timeline has a value for currentTime. 34 await waitForNextFrame(); 35 const timeline = new ViewTimeline({ subject: target }); 36 await waitForNextFrame(); 37 38 let animationstart_events = 0; 39 let animationend_events = 0; 40 document.addEventListener('animationstart', () => { 41 animationstart_events++; 42 }); 43 document.addEventListener('animationend', () => { 44 animationend_events++; 45 }); 46 47 // Start the animation and swap out its timeline while still play-pending 48 // so that it already has a value for current time. 49 target.classList.add('animate'); 50 const anim = target.getAnimations(); 51 anim.timeline = timeline; 52 // Introduce a style change that will make the timeline state stale when 53 // "ticked" at the start of the next animation frame. 54 target.style = 'margin-top: 150vh'; 55 56 assert_false(!!anim.startTime, 57 'Start time deferred until timeline is updated'); 58 59 // Verify that we are not evaluating a start time based on a stale timeline. 60 await waitForNextFrame(); 61 await waitForNextFrame(); 62 assert_equals(animationstart_events, 0, 63 'Target initially off-screen and no animationstart event'); 64 assert_equals(animationend_events, 0, 65 'Target initially off-screen and no animationend event'); 66 67 const scroller = document.scrollingElement; 68 scroller.scrollTop = target.getBoundingClientRect().top; 69 await waitForNextFrame(); 70 await waitForNextFrame(); 71 72 assert_equals(animationstart_events, 1, 73 'scrollstart event received after scrolling into view.'); 74 assert_equals(animationend_events, 0, 75 "No scrollend event until after scrolling out of view"); 76 77 scroller.scrollTop = target.getBoundingClientRect().bottom; 78 79 await waitForNextFrame(); 80 await waitForNextFrame(); 81 82 assert_equals(animationstart_events, 1, 83 'No additional scrollstart event'); 84 assert_equals(animationend_events, 1, 85 'scrollend event received after scrolling out of view'); 86 }, 'View timelime generates animationstart and animationend events'); 87 </script>