tor-browser

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

setting-playback-rate.html (11399B)


      1 <!DOCTYPE html>
      2 <meta charset=utf-8>
      3 <title>Setting the playback rate of an animation that is using a ScrollTimeline</title>
      4 <link rel="help" href="https://drafts.csswg.org/web-animations/#setting-the-playback-rate-of-an-animation">
      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="testcommon.js"></script>
      9 <style>
     10 .scroller {
     11  overflow: auto;
     12  height: 100px;
     13  width: 100px;
     14  will-change: transform;
     15 }
     16 .contents {
     17  height: 1000px;
     18  width: 100%;
     19 }
     20 </style>
     21 <body>
     22 <script>
     23  'use strict';
     24 
     25  promise_test(async t => {
     26    const animation = createScrollLinkedAnimation(t);
     27    const scroller = animation.timeline.source;
     28    // this forces a layout which results in an active timeline
     29    scroller.scrollTop = 0;
     30    // Wait for new animation frame  which allows the timeline to compute new
     31    // current time.
     32    await waitForNextFrame();
     33 
     34    animation.playbackRate = 0.5;
     35    animation.play();
     36    await animation.ready;
     37 
     38    assert_percents_equal(animation.currentTime, 0,
     39        'Zero current time is not affected by playbackRate change.');
     40  }, 'Zero current time is not affected by playbackRate set while the ' +
     41       'animation is in idle state.');
     42 
     43  promise_test(async t => {
     44    const animation = createScrollLinkedAnimation(t);
     45    const scroller = animation.timeline.source;
     46    // this forces a layout which results in an active timeline
     47    scroller.scrollTop = 0;
     48    // Wait for new animation frame  which allows the timeline to compute new
     49    // current time.
     50    await waitForNextFrame();
     51 
     52    animation.play();
     53    await animation.ready;
     54    animation.playbackRate = 0.5;
     55 
     56    assert_percents_equal(animation.currentTime, 0,
     57        'Zero current time is not affected by playbackRate change.');
     58  }, 'Zero current time is not affected by playbackRate set while the ' +
     59      'animation is in play-pending state.');
     60 
     61  promise_test(async t => {
     62    const animation = createScrollLinkedAnimation(t);
     63    const scroller = animation.timeline.source;
     64    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
     65    scroller.scrollTop = 0.2 * maxScroll;
     66    // Wait for new animation frame  which allows the timeline to compute new
     67    // current time.
     68    await waitForNextFrame();
     69 
     70    animation.playbackRate = 0.5;
     71    animation.play();
     72    await animation.ready;
     73    assert_percents_equal(animation.currentTime, 10,
     74        'Initial current time is scaled by playbackRate change.');
     75  }, 'Initial current time is scaled by playbackRate set while ' +
     76      'scroll-linked animation is in running state.');
     77 
     78  promise_test(async t => {
     79    const animation = createScrollLinkedAnimation(t);
     80    const scroller = animation.timeline.source;
     81    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
     82    const playbackRate = 2;
     83 
     84    scroller.scrollTop = 0.2 * maxScroll;
     85    // Wait for new animation frame  which allows the timeline to compute new
     86    // current time.
     87    await waitForNextFrame();
     88 
     89    animation.play();
     90    await animation.ready;
     91    // Set playback rate while the animation is playing.
     92    animation.playbackRate = playbackRate;
     93    assert_percents_equal(animation.currentTime, 40,
     94        'The current time is scaled by the playback rate.');
     95  }, 'The current time is scaled by playbackRate set while the ' +
     96      'scroll-linked animation is in play state.');
     97 
     98  promise_test(async t => {
     99    const animation = createScrollLinkedAnimation(t);
    100    const scroller = animation.timeline.source;
    101    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    102 
    103    // Set playback rate while the animation is in 'idle' state.
    104    animation.playbackRate = 2;
    105    animation.play();
    106    await animation.ready;
    107 
    108    // Wait for new animation frame  which allows the timeline to compute new
    109    // current time.
    110    await runAndWaitForFrameUpdate(() => {
    111      scroller.scrollTop = 0.2 * maxScroll;
    112    });
    113 
    114    assert_percents_equal(animation.currentTime, 40,
    115                          'The current time should increase two times faster ' +
    116                          'than timeline time.');
    117  }, 'The playback rate set before scroll-linked animation started playing ' +
    118      'affects the rate of progress of the current time');
    119 
    120  promise_test(async t => {
    121    const animation = createScrollLinkedAnimation(t);
    122    const scroller = animation.timeline.source;
    123    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    124    animation.play();
    125 
    126    await animation.ready;
    127 
    128    animation.playbackRate = 2;
    129    scroller.scrollTop = 0.25 * maxScroll;
    130    // Wait for new animation frame  which allows the timeline to compute new
    131    // current time.
    132    await waitForNextFrame();
    133 
    134    assert_percents_equal(
    135        animation.currentTime,
    136        animation.timeline.currentTime.value * animation.playbackRate,
    137        'The current time should increase two times faster than timeline time');
    138  }, 'The playback rate affects the rate of progress of the current time' +
    139     ' when scrolling');
    140 
    141  promise_test(async t => {
    142    const animation = createScrollLinkedAnimation(t);
    143    animation.play();
    144    // Setting the current time while play-pending sets the hold time and not
    145    // the start time. currentTime is unaffected by playback rate until no
    146    // longer pending.
    147    animation.currentTime = CSSNumericValue.parse("25%");
    148    animation.playbackRate = 2;
    149 
    150    assert_equals(animation.playState, "running");
    151    assert_true(animation.pending);
    152    assert_percents_equal(animation.currentTime, 25);
    153    await animation.ready;
    154    assert_percents_equal(animation.currentTime, 25);
    155  }, 'Setting the playback rate while play-pending does not scale current ' +
    156     'time.');
    157 
    158  promise_test(async t => {
    159    const animation = createScrollLinkedAnimation(t);
    160    const scroller = animation.timeline.source;
    161    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    162    scroller.scrollTop = 0.25 * maxScroll;
    163    animation.play();
    164    await animation.ready;
    165    animation.playbackRate = 2;
    166 
    167    assert_percents_equal(animation.currentTime, 50);
    168  }, 'Setting the playback rate while playing scales current time.');
    169 
    170  promise_test(async t => {
    171    const animation = createScrollLinkedAnimation(t);
    172 
    173    animation.play();
    174    animation.currentTime = CSSNumericValue.parse("25%");
    175    await animation.ready;
    176    animation.playbackRate = 2;
    177 
    178    assert_percents_equal(animation.currentTime, 50);
    179  }, 'Setting the playback rate while playing scales the set current time.');
    180 
    181  promise_test(async t => {
    182    const animation = createScrollLinkedAnimation(t);
    183    const scroller = animation.timeline.source;
    184    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    185    animation.playbackRate = -1;
    186    scroller.scrollTop = 0.3 * maxScroll;
    187    // Wait for new animation frame  which allows the timeline to compute new
    188    // current time.
    189    await waitForNextFrame();
    190    animation.play();
    191 
    192    await animation.ready;
    193    const expectedCurrentTime = 100 - animation.timeline.currentTime.value;
    194    assert_percents_equal(animation.currentTime, expectedCurrentTime);
    195  }, 'Negative initial playback rate should correctly modify initial current' +
    196    ' time.');
    197 
    198  promise_test(async t => {
    199    const animation = createScrollLinkedAnimation(t);
    200    const scroller = animation.timeline.source;
    201    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    202    scroller.scrollTop = 0.5 * maxScroll;
    203    animation.play();
    204 
    205    await animation.ready;
    206    const startingTimelineTime = animation.timeline.currentTime;
    207    const startingCurrentTime = animation.currentTime;
    208    assert_percents_equal(startingCurrentTime, 50);
    209    assert_percents_equal(startingTimelineTime, 50);
    210 
    211    animation.playbackRate = -1;
    212 
    213    await runAndWaitForFrameUpdate(() => {
    214      scroller.scrollTop = 0.8 * maxScroll;
    215    });
    216    // -300 = 500 - 800
    217 
    218    // let timelineDiff =
    219    //     startingTimelineTime.value - animation.timeline.currentTime.value;
    220    // // 200 = 500 + (-300)
    221    // let expected = startingCurrentTime.value + timelineDiff;
    222    assert_percents_equal(animation.timeline.currentTime, 80);
    223    assert_percents_equal(animation.currentTime, 20);
    224 
    225    await runAndWaitForFrameUpdate(() => {
    226      scroller.scrollTop = 0.2 * maxScroll;
    227    });
    228    // // 300 = 500 - 200
    229    // timelineDiff =
    230    //     startingTimelineTime.value - animation.timeline.currentTime.value;
    231    // // 800 = 500 + 300
    232    // expected = startingCurrentTime.value + timelineDiff;
    233    assert_percents_equal(animation.timeline.currentTime, 20);
    234    assert_percents_equal(animation.currentTime, 80);
    235  }, 'Reversing the playback rate while playing correctly impacts current' +
    236    ' time during future scrolls');
    237 
    238  promise_test(async t => {
    239    const animation = createScrollLinkedAnimation(t);
    240    const scroller = animation.timeline.source;
    241    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    242    animation.playbackRate = 0;
    243    scroller.scrollTop = 0.3 * maxScroll;
    244    // Wait for new animation frame  which allows the timeline to compute new
    245    // current time.
    246    await waitForNextFrame();
    247    animation.play();
    248 
    249    await animation.ready;
    250    assert_percents_equal(animation.currentTime, 0);
    251  }, 'Zero initial playback rate should correctly modify initial current' +
    252    ' time.');
    253 
    254  promise_test(async t => {
    255    const animation = createScrollLinkedAnimation(t);
    256    const scroller = animation.timeline.source;
    257    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    258    scroller.scrollTop = 0.2 * maxScroll;
    259    // Wait for new animation frame  which allows the timeline to compute new
    260    // current time.
    261    await waitForNextFrame();
    262    animation.play();
    263 
    264    await animation.ready;
    265    assert_percents_equal(animation.currentTime, 20);
    266    await runAndWaitForFrameUpdate(() => {
    267      animation.playbackRate = 0;
    268      scroller.scrollTop = 0.5 * maxScroll;
    269    });
    270 
    271    // Ensure that current time does not change.
    272    assert_percents_equal(animation.timeline.currentTime, 50);
    273    assert_percents_equal(animation.currentTime, 0);
    274  }, 'Setting a zero playback rate while running preserves the start time');
    275 
    276 
    277 promise_test(async t => {
    278    const animation = createScrollLinkedAnimation(t);
    279    const scroller = animation.timeline.source;
    280    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    281    scroller.scrollTop = 0.2 * maxScroll;
    282    // Wait for new animation frame  which allows the timeline to compute new
    283    // current time.
    284    await waitForNextFrame();
    285    animation.play();
    286 
    287    await animation.ready;
    288    assert_percents_equal(animation.timeline.currentTime, 20);
    289    assert_percents_equal(animation.currentTime, 20);
    290    animation.startTime = animation.currentTime;
    291    // timeline current time [0%, 100%] --> animation current time [-20%, 80%].
    292    assert_percents_equal(animation.currentTime, 0);
    293 
    294    animation.playbackRate = -1;
    295    // timeline current time [0%, 100%] --> animation current time [80%, -20%].
    296    // timeline @ 20% --> animation current time @ (20% - 80%) * (-1) = 60%.
    297    assert_percents_equal(animation.timeline.currentTime, 20);
    298    assert_percents_equal(animation.currentTime, 60);
    299  }, 'Reversing an animation with non-boundary aligned start time ' +
    300     'symmetrically adjusts the start time');
    301 
    302 </script>
    303 </body>