tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

animation-trigger-state.tentative.html (7513B)


      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 both;
     24      }
     25 
     26      #scroll_target {
     27        animation-trigger: --scrolltrigger play-once pause;
     28        timeline-trigger: --scrolltrigger scroll() 150px 200px;
     29      }
     30      #view_target {
     31        animation-trigger: --viewtrigger play-once pause;
     32        timeline-trigger: --viewtrigger view() 150px 200px;
     33      }
     34      #deferred_target {
     35        animation-trigger: --deferredtrigger play-once pause;
     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 testStateAnimationTrigger(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"], [false, false]);
     81 
     82        // This skips the trigger range and should not play the animation.
     83        await testAnimationTrigger(test, () => {
     84            return rangeBoundaries.exitTriggerRangeBelow();
     85          }, target, ["animationstart", "animationend"], [false, false]);
     86 
     87        const initial_transform = getComputedStyle(target).transform;
     88        // This is a state trigger, entering the trigger range plays the
     89        // animation.
     90        await testAnimationTrigger(test, async () => {
     91            // Enter the range.
     92            await rangeBoundaries.enterTriggerRange();
     93            await waitForAnimationFrames(5);
     94            // Expect some progress.
     95            assert_not_equals(getComputedStyle(target).transform,
     96              initial_transform);
     97            // Exit the range, which should pause the animation.
     98            return rangeBoundaries.exitExitRangeBelow();
     99          }, target, ["animationstart", "animationend", "animationcancel"],
    100          [true, false, false]);
    101        let partial_transform = getComputedStyle(target).transform;
    102 
    103        // Wait a few frames, then check that the animation is still paused.
    104        await waitForAnimationFrames(5);
    105        assert_equals(getComputedStyle(target).transform, partial_transform);
    106 
    107        // This enters the trigger range and should continue the animation.
    108        // Let it play till the end.
    109        await testAnimationTrigger(test, () => {
    110            return rangeBoundaries.enterTriggerRange();
    111          }, target, ["animationstart", "animationend"], [false, true]);
    112        let final_transform = getComputedStyle(target).transform;
    113 
    114        // Exit the range. This should have no effect as the animation has
    115        // already finished.
    116        await testAnimationTrigger(test, async () => {
    117            return rangeBoundaries.exitExitRangeAbove();
    118          }, target, ["animationstart", "animationend", "animationcancel"],
    119          [false, false, false]);
    120 
    121        // Wait a few frames. Exiting the animation should make no difference;
    122        // the animation is already finished.
    123        await waitForAnimationFrames(5);
    124        assert_equals(getComputedStyle(target).transform, final_transform);
    125 
    126        // Enter the range again. This should make no difference. The animation
    127        // is already finished.
    128        await testAnimationTrigger(test, async () => {
    129            return rangeBoundaries.enterTriggerRange();
    130          }, target, ["animationstart", "animationend", "animationcancel"],
    131          [false, false, false]);
    132 
    133        // Wait a few frames. Check the animation is still at the end.
    134        await waitForAnimationFrames(5);
    135        assert_equals(getComputedStyle(target).transform, final_transform);
    136      }
    137 
    138      // The trigger and exit ranges are the same for this test.
    139      const CSS_TRIGGER_START_PX = 150;
    140      const CSS_TRIGGER_END_PX = 200;
    141 
    142      promise_test(async (test) => {
    143        scroller = scroll_scroller;
    144        target = scroll_target;
    145 
    146        const rangeBoundaries = getRangeBoundariesForTest(CSS_TRIGGER_START_PX,
    147                                                          CSS_TRIGGER_END_PX,
    148                                                          CSS_TRIGGER_START_PX,
    149                                                          CSS_TRIGGER_END_PX,
    150                                                          scroller);
    151        await testStateAnimationTrigger(test, rangeBoundaries);
    152      }, "once animation triggered via scroll() timeline.");
    153 
    154      promise_test(async (test) => {
    155        scroller = view_scroller;
    156        target = view_target;
    157 
    158        const COVER_START_OFFSET = 100;
    159 
    160        const rangeBoundaries = getRangeBoundariesForTest(
    161                                      COVER_START_OFFSET + CSS_TRIGGER_START_PX,
    162                                      COVER_START_OFFSET + CSS_TRIGGER_END_PX,
    163                                      COVER_START_OFFSET + CSS_TRIGGER_START_PX,
    164                                      COVER_START_OFFSET + CSS_TRIGGER_END_PX,
    165                                      scroller);
    166        await testStateAnimationTrigger(test, rangeBoundaries);
    167      }, "once animation triggered via view() timeline.");
    168 
    169      promise_test(async (test) => {
    170        scroller = deferred_scroller;
    171        target = deferred_target;
    172 
    173        const COVER_START_OFFSET = 100;
    174 
    175        const rangeBoundaries = getRangeBoundariesForTest(
    176                                      COVER_START_OFFSET + CSS_TRIGGER_START_PX,
    177                                      COVER_START_OFFSET + CSS_TRIGGER_END_PX,
    178                                      COVER_START_OFFSET + CSS_TRIGGER_START_PX,
    179                                      COVER_START_OFFSET + CSS_TRIGGER_END_PX,
    180                                      scroller);
    181        await testStateAnimationTrigger(test, rangeBoundaries);
    182      }, "once animation triggered via deferred (view) timeline.");
    183    </script>
    184  </body>
    185 </html>