tor-browser

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

updateTiming.html (19054B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>AnimationEffect.updateTiming</title>
      4 <link rel="help" href="https://drafts.csswg.org/web-animations-1/#dom-animationeffect-updatetiming">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="../../testcommon.js"></script>
      8 <script src="../../resources/easing-tests.js"></script>
      9 <script src="../../resources/timing-tests.js"></script>
     10 <body>
     11 <div id="log"></div>
     12 <script>
     13 'use strict';
     14 
     15 // ------------------------------
     16 //  delay
     17 // ------------------------------
     18 
     19 test(t => {
     20  const anim = createDiv(t).animate(null, 100);
     21  anim.effect.updateTiming({ delay: 100 });
     22  assert_equals(anim.effect.getTiming().delay, 100, 'set delay 100');
     23  assert_equals(anim.effect.getComputedTiming().delay, 100,
     24                  'getComputedTiming() after set delay 100');
     25 }, 'Allows setting the delay to a positive number');
     26 
     27 test(t => {
     28  const anim = createDiv(t).animate(null, 100);
     29  anim.effect.updateTiming({ delay: -100 });
     30  assert_equals(anim.effect.getTiming().delay, -100, 'set delay -100');
     31  assert_equals(anim.effect.getComputedTiming().delay, -100,
     32                'getComputedTiming() after set delay -100');
     33 }, 'Allows setting the delay to a negative number');
     34 
     35 test(t => {
     36  const anim = createDiv(t).animate(null, 100);
     37  anim.effect.updateTiming({ delay: 100 });
     38  assert_equals(anim.effect.getComputedTiming().progress, null);
     39  assert_equals(anim.effect.getComputedTiming().currentIteration, null);
     40 }, 'Allows setting the delay of an animation in progress: positive delay that'
     41   + ' causes the animation to be no longer in-effect');
     42 
     43 test(t => {
     44  const anim = createDiv(t).animate(null, { fill: 'both', duration: 100 });
     45  anim.effect.updateTiming({ delay: -50 });
     46  assert_equals(anim.effect.getComputedTiming().progress, 0.5);
     47 }, 'Allows setting the delay of an animation in progress: negative delay that'
     48   + ' seeks into the active interval');
     49 
     50 test(t => {
     51  const anim = createDiv(t).animate(null, { fill: 'both', duration: 100 });
     52  anim.effect.updateTiming({ delay: -100 });
     53  assert_equals(anim.effect.getComputedTiming().progress, 1);
     54  assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
     55 }, 'Allows setting the delay of an animation in progress: large negative delay'
     56   + ' that causes the animation to be finished');
     57 
     58 for (const invalid of gBadDelayValues) {
     59  test(t => {
     60    const anim = createDiv(t).animate(null);
     61    assert_throws_js(TypeError, () => {
     62      anim.effect.updateTiming({ delay: invalid });
     63    });
     64  }, `Throws when setting invalid delay value: ${invalid}`);
     65 }
     66 
     67 
     68 // ------------------------------
     69 //  endDelay
     70 // ------------------------------
     71 
     72 test(t => {
     73  const anim = createDiv(t).animate(null, 2000);
     74  anim.effect.updateTiming({ endDelay: 123.45 });
     75  assert_time_equals_literal(anim.effect.getTiming().endDelay, 123.45,
     76                             'set endDelay 123.45');
     77  assert_time_equals_literal(anim.effect.getComputedTiming().endDelay, 123.45,
     78                             'getComputedTiming() after set endDelay 123.45');
     79 }, 'Allows setting the endDelay to a positive number');
     80 
     81 test(t => {
     82  const anim = createDiv(t).animate(null, 2000);
     83  anim.effect.updateTiming({ endDelay: -1000 });
     84  assert_equals(anim.effect.getTiming().endDelay, -1000, 'set endDelay -1000');
     85  assert_equals(anim.effect.getComputedTiming().endDelay, -1000,
     86                'getComputedTiming() after set endDelay -1000');
     87 }, 'Allows setting the endDelay to a negative number');
     88 
     89 test(t => {
     90  const anim = createDiv(t).animate(null, 2000);
     91  assert_throws_js(TypeError, () => {
     92    anim.effect.updateTiming({ endDelay: Infinity });
     93  });
     94 }, 'Throws when setting the endDelay to infinity');
     95 
     96 test(t => {
     97  const anim = createDiv(t).animate(null, 2000);
     98  assert_throws_js(TypeError, () => {
     99    anim.effect.updateTiming({ endDelay: -Infinity });
    100  });
    101 }, 'Throws when setting the endDelay to negative infinity');
    102 
    103 
    104 // ------------------------------
    105 //  fill
    106 // ------------------------------
    107 
    108 for (const fill of ['none', 'forwards', 'backwards', 'both']) {
    109  test(t => {
    110    const anim = createDiv(t).animate(null, 100);
    111    anim.effect.updateTiming({ fill });
    112    assert_equals(anim.effect.getTiming().fill, fill, 'set fill ' + fill);
    113    assert_equals(anim.effect.getComputedTiming().fill, fill,
    114                  'getComputedTiming() after set fill ' + fill);
    115  }, `Allows setting the fill to '${fill}'`);
    116 }
    117 
    118 
    119 // ------------------------------
    120 //  iterationStart
    121 // ------------------------------
    122 
    123 test(t => {
    124  const anim = createDiv(t).animate(null,
    125                                    { iterationStart: 0.2,
    126                                      iterations: 1,
    127                                      fill: 'both',
    128                                      duration: 100,
    129                                      delay: 1 });
    130  anim.effect.updateTiming({ iterationStart: 2.5 });
    131  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
    132  assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
    133 }, 'Allows setting the iterationStart of an animation in progress:'
    134   + ' backwards-filling');
    135 
    136 test(t => {
    137  const anim = createDiv(t).animate(null,
    138                                    { iterationStart: 0.2,
    139                                      iterations: 1,
    140                                      fill: 'both',
    141                                      duration: 100,
    142                                      delay: 0 });
    143  anim.effect.updateTiming({ iterationStart: 2.5 });
    144  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
    145  assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
    146 }, 'Allows setting the iterationStart of an animation in progress:'
    147   + ' active phase');
    148 
    149 test(t => {
    150  const anim = createDiv(t).animate(null,
    151                                    { iterationStart: 0.2,
    152                                      iterations: 1,
    153                                      fill: 'both',
    154                                      duration: 100,
    155                                      delay: 0 });
    156  anim.finish();
    157  anim.effect.updateTiming({ iterationStart: 2.5 });
    158  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
    159  assert_equals(anim.effect.getComputedTiming().currentIteration, 3);
    160 }, 'Allows setting the iterationStart of an animation in progress:'
    161   + ' forwards-filling');
    162 
    163 for (const invalid of gBadIterationStartValues) {
    164  test(t => {
    165    const anim = createDiv(t).animate(null);
    166    assert_throws_js(TypeError, () => {
    167      anim.effect.updateTiming({ iterationStart: invalid });
    168    }, `setting ${invalid}`);
    169  }, `Throws when setting invalid iterationStart value: ${invalid}`);
    170 }
    171 
    172 // ------------------------------
    173 //  iterations
    174 // ------------------------------
    175 
    176 test(t => {
    177  const anim = createDiv(t).animate(null, 2000);
    178  anim.effect.updateTiming({ iterations: 2 });
    179  assert_equals(anim.effect.getTiming().iterations, 2, 'set duration 2');
    180  assert_equals(anim.effect.getComputedTiming().iterations, 2,
    181                       'getComputedTiming() after set iterations 2');
    182 }, 'Allows setting iterations to a double value');
    183 
    184 test(t => {
    185  const anim = createDiv(t).animate(null, 2000);
    186  anim.effect.updateTiming({ iterations: Infinity });
    187  assert_equals(anim.effect.getTiming().iterations, Infinity,
    188                'set duration Infinity');
    189  assert_equals(anim.effect.getComputedTiming().iterations, Infinity,
    190                       'getComputedTiming() after set iterations Infinity');
    191 }, 'Allows setting iterations to infinity');
    192 
    193 for (const invalid of gBadIterationsValues) {
    194  test(t => {
    195    const anim = createDiv(t).animate(null);
    196    assert_throws_js(TypeError, () => {
    197      anim.effect.updateTiming({ iterations: invalid });
    198    });
    199  }, `Throws when setting invalid iterations value: ${invalid}`);
    200 }
    201 
    202 test(t => {
    203  const anim = createDiv(t).animate(null, { duration: 100000, fill: 'both' });
    204 
    205  anim.finish();
    206 
    207  assert_equals(anim.effect.getComputedTiming().progress, 1,
    208                'progress when animation is finished');
    209  assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
    210                'current iteration when animation is finished');
    211 
    212  anim.effect.updateTiming({ iterations: 2 });
    213 
    214  assert_time_equals_literal(anim.effect.getComputedTiming().progress,
    215                             0,
    216                             'progress after adding an iteration');
    217  assert_time_equals_literal(anim.effect.getComputedTiming().currentIteration,
    218                             1,
    219                             'current iteration after adding an iteration');
    220 
    221  anim.effect.updateTiming({ iterations: 0 });
    222 
    223  assert_equals(anim.effect.getComputedTiming().progress, 0,
    224                'progress after setting iterations to zero');
    225  assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
    226                'current iteration after setting iterations to zero');
    227 
    228  anim.effect.updateTiming({ iterations: Infinity });
    229 
    230  assert_equals(anim.effect.getComputedTiming().progress, 0,
    231                'progress after setting iterations to Infinity');
    232  assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
    233                'current iteration after setting iterations to Infinity');
    234 }, 'Allows setting the iterations of an animation in progress');
    235 
    236 
    237 // ------------------------------
    238 //  duration
    239 // ------------------------------
    240 
    241 for (const duration of gGoodDurationValues) {
    242  test(t => {
    243    const anim = createDiv(t).animate(null, 2000);
    244    anim.effect.updateTiming({ duration: duration.specified });
    245    if (typeof duration.specified === 'number') {
    246      assert_time_equals_literal(anim.effect.getTiming().duration,
    247                                 duration.specified,
    248                                 'Updates specified duration');
    249    } else {
    250      assert_equals(anim.effect.getTiming().duration, duration.specified,
    251                    'Updates specified duration');
    252    }
    253    assert_time_equals_literal(anim.effect.getComputedTiming().duration,
    254                               duration.computed,
    255                               'Updates computed duration');
    256  }, `Allows setting the duration to ${duration.specified}`);
    257 }
    258 
    259 for (const invalid of gBadDurationValues) {
    260  test(t => {
    261    assert_throws_js(TypeError, () => {
    262      createDiv(t).animate(null, { duration: invalid });
    263    });
    264  }, 'Throws when setting invalid duration: '
    265     + (typeof invalid === 'string' ? `"${invalid}"` : invalid));
    266 }
    267 
    268 test(t => {
    269  const anim = createDiv(t).animate(null, { duration: 100000, fill: 'both' });
    270  anim.finish();
    271  assert_equals(anim.effect.getComputedTiming().progress, 1,
    272                'progress when animation is finished');
    273  anim.effect.updateTiming({ duration: anim.effect.getTiming().duration * 2 });
    274  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5,
    275                             'progress after doubling the duration');
    276  anim.effect.updateTiming({ duration: 0 });
    277  assert_equals(anim.effect.getComputedTiming().progress, 1,
    278                'progress after setting duration to zero');
    279  anim.effect.updateTiming({ duration: 'auto' });
    280  assert_equals(anim.effect.getComputedTiming().progress, 1,
    281                'progress after setting duration to \'auto\'');
    282 }, 'Allows setting the duration of an animation in progress');
    283 
    284 promise_test(t => {
    285  const anim = createDiv(t).animate(null, 100 * MS_PER_SEC);
    286  return anim.ready.then(() => {
    287    const originalStartTime   = anim.startTime;
    288    const originalCurrentTime = anim.currentTime;
    289    assert_time_equals_literal(
    290      anim.effect.getComputedTiming().duration,
    291      100 * MS_PER_SEC,
    292      'Initial duration should be as set on KeyframeEffect'
    293    );
    294 
    295    anim.effect.updateTiming({ duration: 200 * MS_PER_SEC });
    296    assert_time_equals_literal(
    297      anim.effect.getComputedTiming().duration,
    298      200 * MS_PER_SEC,
    299      'Effect duration should have been updated'
    300    );
    301    assert_times_equal(anim.startTime, originalStartTime,
    302                       'startTime should be unaffected by changing effect ' +
    303                       'duration');
    304    assert_times_equal(anim.currentTime, originalCurrentTime,
    305                       'currentTime should be unaffected by changing effect ' +
    306                       'duration');
    307  });
    308 }, 'Allows setting the duration of an animation in progress such that the' +
    309   ' the start and current time do not change');
    310 
    311 
    312 // ------------------------------
    313 //  direction
    314 // ------------------------------
    315 
    316 test(t => {
    317  const anim = createDiv(t).animate(null, 2000);
    318 
    319  const directions = ['normal', 'reverse', 'alternate', 'alternate-reverse'];
    320  for (const direction of directions) {
    321    anim.effect.updateTiming({ direction: direction });
    322    assert_equals(anim.effect.getTiming().direction, direction,
    323                  `set direction to ${direction}`);
    324  }
    325 }, 'Allows setting the direction to each of the possible keywords');
    326 
    327 test(t => {
    328  const anim = createDiv(t).animate(null, {
    329    duration: 10000,
    330    direction: 'normal',
    331  });
    332  anim.currentTime = 7000;
    333  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
    334                             'progress before updating direction');
    335 
    336  anim.effect.updateTiming({ direction: 'reverse' });
    337 
    338  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
    339                             'progress after updating direction');
    340 }, 'Allows setting the direction of an animation in progress from \'normal\' to'
    341   + ' \'reverse\'');
    342 
    343 test(t => {
    344  const anim = createDiv(t).animate(null,
    345                                    { duration: 10000, direction: 'normal' });
    346  assert_equals(anim.effect.getComputedTiming().progress, 0,
    347                'progress before updating direction');
    348 
    349  anim.effect.updateTiming({ direction: 'reverse' });
    350 
    351  assert_equals(anim.effect.getComputedTiming().progress, 1,
    352                'progress after updating direction');
    353 }, 'Allows setting the direction of an animation in progress from \'normal\' to'
    354   + ' \'reverse\' while at start of active interval');
    355 
    356 test(t => {
    357  const anim = createDiv(t).animate(null,
    358                                    { fill: 'backwards',
    359                                      duration: 10000,
    360                                      delay: 10000,
    361                                      direction: 'normal' });
    362  assert_equals(anim.effect.getComputedTiming().progress, 0,
    363                'progress before updating direction');
    364 
    365  anim.effect.updateTiming({ direction: 'reverse' });
    366 
    367  assert_equals(anim.effect.getComputedTiming().progress, 1,
    368                'progress after updating direction');
    369 }, 'Allows setting the direction of an animation in progress from \'normal\' to'
    370   + ' \'reverse\' while filling backwards');
    371 
    372 test(t => {
    373  const anim = createDiv(t).animate(null,
    374                                    { iterations: 2,
    375                                      duration: 10000,
    376                                      direction: 'normal' });
    377  anim.currentTime = 17000;
    378  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
    379                             'progress before updating direction');
    380 
    381  anim.effect.updateTiming({ direction: 'alternate' });
    382 
    383  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
    384                             'progress after updating direction');
    385 }, 'Allows setting the direction of an animation in progress from \'normal\' to'
    386   + ' \'alternate\'');
    387 
    388 test(t => {
    389  const anim = createDiv(t).animate(null,
    390                                    { iterations: 2,
    391                                      duration: 10000,
    392                                      direction: 'alternate' });
    393  anim.currentTime = 17000;
    394  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3,
    395                             'progress before updating direction');
    396 
    397  anim.effect.updateTiming({ direction: 'alternate-reverse' });
    398 
    399  assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.7,
    400                             'progress after updating direction');
    401 }, 'Allows setting the direction of an animation in progress from \'alternate\''
    402   + ' to \'alternate-reverse\'');
    403 
    404 
    405 // ------------------------------
    406 //  easing
    407 // ------------------------------
    408 
    409 function assert_progress(animation, currentTime, easingFunction) {
    410  animation.currentTime = currentTime;
    411  const portion = currentTime / animation.effect.getTiming().duration;
    412  assert_approx_equals(animation.effect.getComputedTiming().progress,
    413                       easingFunction(portion),
    414                       0.01,
    415                       'The progress of the animation should be approximately'
    416                       + ` ${easingFunction(portion)} at ${currentTime}ms`);
    417 }
    418 
    419 for (const options of gEasingTests) {
    420  test(t => {
    421    const target = createDiv(t);
    422    const anim = target.animate(null,
    423                                { duration: 1000 * MS_PER_SEC,
    424                                  fill: 'forwards' });
    425    anim.effect.updateTiming({ easing: options.easing });
    426    assert_equals(anim.effect.getTiming().easing,
    427                  options.serialization || options.easing);
    428 
    429    const easing = options.easingFunction;
    430    assert_progress(anim, 0, easing);
    431    assert_progress(anim, 250 * MS_PER_SEC, easing);
    432    assert_progress(anim, 500 * MS_PER_SEC, easing);
    433    assert_progress(anim, 750 * MS_PER_SEC, easing);
    434    assert_progress(anim, 1000 * MS_PER_SEC, easing);
    435  }, `Allows setting the easing to a ${options.desc}`);
    436 }
    437 
    438 for (const easing of gRoundtripEasings) {
    439  test(t => {
    440    const anim = createDiv(t).animate(null);
    441    anim.effect.updateTiming({ easing: easing });
    442    assert_equals(anim.effect.getTiming().easing, easing);
    443  }, `Updates the specified value when setting the easing to '${easing}'`);
    444 }
    445 
    446 test(t => {
    447  const delay = 1000 * MS_PER_SEC;
    448 
    449  const target = createDiv(t);
    450  const anim = target.animate(null,
    451                              { duration: 1000 * MS_PER_SEC,
    452                                fill: 'both',
    453                                delay: delay,
    454                                easing: 'steps(2, start)' });
    455 
    456  anim.effect.updateTiming({ easing: 'steps(2, end)' });
    457  assert_equals(anim.effect.getComputedTiming().progress, 0,
    458                'easing replace to steps(2, end) at before phase');
    459 
    460  anim.currentTime = delay + 750 * MS_PER_SEC;
    461  assert_equals(anim.effect.getComputedTiming().progress, 0.5,
    462                'change currentTime to active phase');
    463 
    464  anim.effect.updateTiming({ easing: 'steps(2, start)' });
    465  assert_equals(anim.effect.getComputedTiming().progress, 1,
    466                'easing replace to steps(2, start) at active phase');
    467 
    468  anim.currentTime = delay + 1500 * MS_PER_SEC;
    469  anim.effect.updateTiming({ easing: 'steps(2, end)' });
    470  assert_equals(anim.effect.getComputedTiming().progress, 1,
    471                'easing replace to steps(2, end) again at after phase');
    472 }, 'Allows setting the easing of an animation in progress');
    473 
    474 </script>
    475 </body>