animation-trigger-once.tentative.html (5819B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <link rel="help" src="https://drafts.csswg.org/css-animations-2/#animation-trigger"> 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="/dom/events/scrolling/scroll_support.js"></script> 9 <script src="support/support.js"></script> 10 </head> 11 <body> 12 <style> 13 @keyframes myAnim { 14 from { transform: scaleX(1); } 15 to { transform: scaleX(5); } 16 } 17 .subject, .target { 18 height: 50px; 19 width: 50px; 20 background-color: red; 21 } 22 .target { 23 animation: myAnim linear 0.5s forwards; 24 } 25 26 #scroll_target { 27 animation-trigger: --scrolltrigger play-once; 28 timeline-trigger: --scrolltrigger scroll() 150px 200px; 29 } 30 #view_target { 31 animation-trigger: --viewtrigger play-once; 32 timeline-trigger: --viewtrigger view() 150px 200px; 33 } 34 #deferred_target { 35 animation-trigger: --deferredtrigger play-once; 36 } 37 #deferred_subject { 38 view-timeline: --viewtimeline; 39 timeline-trigger: --deferredtrigger --viewtimeline 150px 200px; 40 } 41 42 .scroller { 43 overflow-y: scroll; 44 height: 500px; 45 width: 500px; 46 border: solid 1px; 47 position: relative; 48 } 49 #wrapper { 50 timeline-scope: --viewtimeline; 51 } 52 #space { 53 width: 50px; 54 height: 600px; 55 } 56 </style> 57 <div id="wrapper"> 58 <div id="scroll_scroller" class="scroller"> 59 <div id="space"></div> 60 <div id="scroll_target" class="subject target" tabindex="0"></div> 61 <div id="space"></div> 62 </div> 63 <div id="view_scroller" class="scroller"> 64 <div id="space"></div> 65 <div id="view_target" class="subject target" tabindex="0"></div> 66 <div id="space"></div> 67 </div> 68 <div id="deferred_scroller" class="scroller"> 69 <div id="space"></div> 70 <div id="deferred_subject" class="subject" tabindex="0"></div> 71 <div id="space"></div> 72 </div> 73 <div id="deferred_target" class="target" tabindex="0"></div> 74 </div> 75 <script> 76 async function testOnceAnimationTrigger(test, rangeBoundaries) { 77 // Just short of the trigger range start, no trigger action expected. 78 await testAnimationTrigger(test, () => { 79 return rangeBoundaries.exitTriggerRangeAbove(); 80 }, target, ["animationstart", "animationend"], 81 [false, false]); 82 83 // This skips the trigger range and should not play the animation. 84 await testAnimationTrigger(test, () => { 85 return rangeBoundaries.exitTriggerRangeBelow(); 86 }, target, ["animationstart", "animationend"], [false, false]); 87 88 // This enters the trigger range and should play the animation. 89 await testAnimationTrigger(test, () => { 90 return rangeBoundaries.enterTriggerRange(); 91 }, target, ["animationstart", "animationend"], [true, true]); 92 93 // This is a once trigger, exiting the exit range has no effect. 94 await testAnimationTrigger(test, () => { 95 return rangeBoundaries.exitExitRangeAbove(); 96 }, target, ["animationcancel", "animationend"], [false, false]); 97 98 // This is a once trigger, re-entering range has no effect. 99 await testAnimationTrigger(test, () => { 100 return rangeBoundaries.enterTriggerRange(); 101 }, target, ["animationstart", "animationend"], [false, false]); 102 } 103 104 // The trigger and exit ranges are the same for this test. 105 const CSS_TRIGGER_START_PX = 150; 106 const CSS_TRIGGER_END_PX = 200; 107 108 promise_test(async (test) => { 109 scroller = scroll_scroller; 110 target = scroll_target; 111 112 const rangeBoundaries = getRangeBoundariesForTest(CSS_TRIGGER_START_PX, 113 CSS_TRIGGER_END_PX, 114 CSS_TRIGGER_START_PX, 115 CSS_TRIGGER_END_PX, 116 scroller); 117 await testOnceAnimationTrigger(test, rangeBoundaries); 118 }, "once animation triggered via scroll() timeline."); 119 120 promise_test(async (test) => { 121 scroller = view_scroller; 122 target = view_target; 123 124 const COVER_START_OFFSET = 100; 125 126 const rangeBoundaries = getRangeBoundariesForTest( 127 COVER_START_OFFSET + CSS_TRIGGER_START_PX, 128 COVER_START_OFFSET + CSS_TRIGGER_END_PX, 129 COVER_START_OFFSET + CSS_TRIGGER_START_PX, 130 COVER_START_OFFSET + CSS_TRIGGER_END_PX, 131 scroller); 132 await testOnceAnimationTrigger(test, rangeBoundaries); 133 }, "once animation triggered via view() timeline."); 134 135 promise_test(async (test) => { 136 scroller = deferred_scroller; 137 target = deferred_target; 138 139 const COVER_START_OFFSET = 100; 140 141 const rangeBoundaries = getRangeBoundariesForTest( 142 COVER_START_OFFSET + CSS_TRIGGER_START_PX, 143 COVER_START_OFFSET + CSS_TRIGGER_END_PX, 144 COVER_START_OFFSET + CSS_TRIGGER_START_PX, 145 COVER_START_OFFSET + CSS_TRIGGER_END_PX, 146 scroller); 147 await testOnceAnimationTrigger(test, rangeBoundaries); 148 }, "once animation triggered via deferred (view) timeline."); 149 </script> 150 </body> 151 </html>