| <!DOCTYPE html> |
| <meta charset=utf-8> |
| <title>AnimationEffectTiming.easing</title> |
| <link rel="help" href="https://drafts.csswg.org/web-animations/#dom-animationeffecttiming-easing"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="../../testcommon.js"></script> |
| <script src="../../resources/easing-tests.js"></script> |
| <body> |
| <div id="log"></div> |
| <script> |
| 'use strict'; |
| |
| test(t => { |
| const anim = createDiv(t).animate(null); |
| assert_equals(anim.effect.timing.easing, 'linear'); |
| }, 'Has the default value \'linear\''); |
| |
| function assert_progress(animation, currentTime, easingFunction) { |
| animation.currentTime = currentTime; |
| const portion = currentTime / animation.effect.timing.duration; |
| assert_approx_equals(animation.effect.getComputedTiming().progress, |
| easingFunction(portion), |
| 0.01, |
| 'The progress of the animation should be approximately' |
| + ` ${easingFunction(portion)} at ${currentTime}ms`); |
| } |
| |
| for (const options of gEasingTests) { |
| test(t => { |
| const target = createDiv(t); |
| const anim = target.animate([ { opacity: 0 }, { opacity: 1 } ], |
| { duration: 1000 * MS_PER_SEC, |
| fill: 'forwards' }); |
| anim.effect.timing.easing = options.easing; |
| assert_equals(anim.effect.timing.easing, |
| options.serialization || options.easing); |
| |
| const easing = options.easingFunction; |
| assert_progress(anim, 0, easing); |
| assert_progress(anim, 250 * MS_PER_SEC, easing); |
| assert_progress(anim, 500 * MS_PER_SEC, easing); |
| assert_progress(anim, 750 * MS_PER_SEC, easing); |
| assert_progress(anim, 1000 * MS_PER_SEC, easing); |
| }, options.desc); |
| } |
| |
| for (const invalidEasing of gInvalidEasings) { |
| test(t => { |
| const div = createDiv(t); |
| const anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC); |
| assert_throws({ name: 'TypeError' }, |
| () => { |
| anim.effect.timing.easing = invalidEasing; |
| }); |
| }, `Throws on invalid easing: '${invalidEasing}'`); |
| } |
| |
| for (const easing of gRoundtripEasings) { |
| test(t => { |
| const anim = createDiv(t).animate(null); |
| anim.effect.timing.easing = easing; |
| assert_equals(anim.effect.timing.easing, easing); |
| }, `Canonical easing '${easing}' is returned as set`); |
| } |
| |
| test(t => { |
| const delay = 1000 * MS_PER_SEC; |
| |
| const target = createDiv(t); |
| const anim = target.animate([ { opacity: 0 }, { opacity: 1 } ], |
| { duration: 1000 * MS_PER_SEC, |
| fill: 'both', |
| delay: delay, |
| easing: 'steps(2, start)' }); |
| |
| anim.effect.timing.easing = 'steps(2, end)'; |
| assert_equals(anim.effect.getComputedTiming().progress, 0, |
| 'easing replace to steps(2, end) at before phase'); |
| |
| anim.currentTime = delay + 750 * MS_PER_SEC; |
| assert_equals(anim.effect.getComputedTiming().progress, 0.5, |
| 'change currentTime to active phase'); |
| |
| anim.effect.timing.easing = 'steps(2, start)'; |
| assert_equals(anim.effect.getComputedTiming().progress, 1, |
| 'easing replace to steps(2, start) at active phase'); |
| |
| anim.currentTime = delay + 1500 * MS_PER_SEC; |
| anim.effect.timing.easing = 'steps(2, end)'; |
| assert_equals(anim.effect.getComputedTiming().progress, 1, |
| 'easing replace to steps(2, end) again at after phase'); |
| }, 'Allows the easing to be changed while the animation is in progress'); |
| |
| </script> |
| </body> |