animation-trigger-disarmed-by-apis.tentative.html (5602B)
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); left: 0px } 15 to { transform: scaleX(5); left: 10px } 16 } 17 .subject, .target { 18 height: 50px; 19 width: 50px; 20 background-color: red; 21 } 22 .scroller { 23 overflow-y: scroll; 24 height: 500px; 25 width: 500px; 26 border: solid 1px; 27 position: relative; 28 } 29 #space { 30 width: 50px; 31 height: 600px; 32 } 33 </style> 34 <div id="wrapper"> 35 <div id="scroller" class="scroller"> 36 <div id="space"></div> 37 <div id="subject" class="subject"></div> 38 <div id="space"></div> 39 </div> 40 <div id="target" class="target"></div> 41 </div> 42 <script> 43 // The trigger and exit ranges are the same for this test. 44 const TRIGGER_START_PX = 150; 45 const TRIGGER_END_PX = 200; 46 47 const scroller = document.getElementById("scroller"); 48 const target = document.getElementById("target"); 49 50 const COVER_START_OFFSET = 100; 51 const rangeBoundaries = getRangeBoundariesForTest( 52 COVER_START_OFFSET + TRIGGER_START_PX, 53 COVER_START_OFFSET + TRIGGER_END_PX, 54 COVER_START_OFFSET + TRIGGER_START_PX, 55 COVER_START_OFFSET + TRIGGER_END_PX, 56 scroller); 57 58 const ANIMATION_DURATION_MS = 1; 59 60 function watchAnimationStatus(animation, targetCurrentTime, 61 targetPlayState, resolve, repeat=2) { 62 if (repeat <= 0) { 63 resolve(); 64 return; 65 } 66 if (targetCurrentTime === null) { 67 assert_equals(animation.currentTime, targetCurrentTime, 68 "currentTime has not changed."); 69 } else { 70 assert_times_equal(animation.currentTime, targetCurrentTime, 1, 71 "currentTime has not changed."); 72 } 73 assert_equals(animation.playState, targetPlayState, 74 "playState has not changed."); 75 requestAnimationFrame(() => { 76 watchAnimationStatus(animation, targetCurrentTime, targetPlayState, 77 resolve, repeat - 1); 78 }); 79 } 80 81 const view_timeline = new ViewTimeline({ subject: subject }); 82 function setupAnimation() { 83 const animation = new Animation( 84 new KeyframeEffect( 85 target, 86 [ 87 { transform: "scaleX(1)", backgroundColor: "pink", left: "0px" }, 88 { transform: "scaleX(5)", backgroundColor: "pink", left: "10px" } 89 ], 90 { duration: ANIMATION_DURATION_MS, fill: "both" } 91 )); 92 return animation; 93 } 94 function setupAnimationTrigger(use_default_trigger=false) { 95 const trigger = new TimelineTrigger({ 96 timeline: view_timeline, 97 rangeStart: `${TRIGGER_START_PX}px`, 98 rangeEnd: `${TRIGGER_END_PX}px` 99 }); 100 return trigger; 101 } 102 103 promise_test(async(test) => { 104 const animation = setupAnimation(); 105 const trigger = setupAnimationTrigger(); 106 107 assert_equals(animation.currentTime, null, 108 "animation is idle; null currentTime."); 109 assert_equals(animation.playState, "idle", "animation is idle."); 110 assert_array_equals(trigger.getAnimations(), [], 111 "trigger has no animations"); 112 113 // Attaching the trigger should simply keep the animaiton paused at 114 // zero currentTime. 115 trigger.addAnimation(animation, "play-forwards", "play-backwards"); 116 await waitForNextFrame(); 117 assert_times_equal(animation.currentTime, 0, 118 "animation is paused at currentTime zero."); 119 assert_equals(animation.playState, "paused", "animation is paused."); 120 assert_array_equals(trigger.getAnimations(), [animation], 121 "trigger has the animation attached"); 122 123 // First, verify that the trigger is indeed active. 124 await rangeBoundaries.enterTriggerRange(); 125 await animation.finished; 126 127 assert_times_equal(animation.currentTime, ANIMATION_DURATION_MS, 128 "animation finished (currentTime)"); 129 assert_equals(animation.playState, "finished", 130 "animation finished (playState)"); 131 assert_array_equals(trigger.getAnimations(), [animation], 132 "trigger has the animation attached"); 133 134 animation.cancel(); 135 136 assert_array_equals(trigger.getAnimations(), [], 137 "trigger has no animations as the animation was cancelled"); 138 139 // Ensure exiting does nothing. 140 status_promise = new Promise(resolve => { 141 watchAnimationStatus(animation, null, "idle", resolve); 142 }); 143 await rangeBoundaries.exitExitRangeAbove(); 144 await status_promise; 145 146 // Ensure re-entering does nothing. 147 status_promise = new Promise(resolve => { 148 watchAnimationStatus(animation, null, "idle", resolve); 149 }); 150 await rangeBoundaries.enterTriggerRange(); 151 await status_promise; 152 153 }, "cancel disables animation trigger"); 154 </script> 155 </body> 156 </html>