631 lines
25 KiB
HTML
631 lines
25 KiB
HTML
<!doctype html>
|
|
<meta charset=utf-8>
|
|
<title>Scroll based animation: AnimationEffect.updateTiming</title>
|
|
<!-- Adapted to progressed based scroll animations from "wpt\web-animations\interfaces\AnimationEffect\updateTiming.html" -->
|
|
<link rel="help" href="https://drafts.csswg.org/web-animations-1/#dom-animationeffect-updatetiming">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/web-animations/testcommon.js"></script>
|
|
<script src="testcommon.js"></script>
|
|
<script src="/web-animations/resources/easing-tests.js"></script>
|
|
<script src="/web-animations/resources/timing-tests.js"></script>
|
|
<style>
|
|
.scroller {
|
|
overflow: auto;
|
|
height: 100px;
|
|
width: 100px;
|
|
will-change: transform;
|
|
}
|
|
.contents {
|
|
height: 1000px;
|
|
width: 100%;
|
|
}
|
|
</style>
|
|
<body>
|
|
<div id="log"></div>
|
|
<script>
|
|
'use strict';
|
|
|
|
// ------------------------------
|
|
// delay
|
|
// ------------------------------
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, {duration: 1000, delay: 200})
|
|
anim.play();
|
|
|
|
assert_equals(anim.effect.getTiming().delay, 200, 'initial delay 200');
|
|
assert_equals(anim.effect.getComputedTiming().delay, 200,
|
|
'getComputedTiming() initially delay 200');
|
|
|
|
anim.effect.updateTiming({ delay: 100 });
|
|
assert_equals(anim.effect.getTiming().delay, 100, 'set delay 100');
|
|
assert_equals(anim.effect.getComputedTiming().delay, 100,
|
|
'getComputedTiming() after set delay 100');
|
|
}, 'Allows setting the delay to a positive number');
|
|
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, {duration: 100, delay: -100})
|
|
anim.play();
|
|
anim.effect.updateTiming({ delay: -100 });
|
|
assert_equals(anim.effect.getTiming().delay, -100, 'set delay -100');
|
|
assert_equals(anim.effect.getComputedTiming().delay, -100,
|
|
'getComputedTiming() after set delay -100');
|
|
assert_percents_equal(anim.effect.getComputedTiming().endTime, 0,
|
|
'getComputedTiming().endTime after set delay -100');
|
|
}, 'Allows setting the delay to a negative number');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, {duration: 100})
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ delay: 100 });
|
|
assert_equals(anim.effect.getComputedTiming().progress, null);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, null);
|
|
}, 'Allows setting the delay of an animation in progress: positive delay that'
|
|
+ ' causes the animation to be no longer in-effect');
|
|
|
|
promise_test(async t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(t, { fill: 'both', duration: 100 });
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ delay: -50 });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0.5);
|
|
}, 'Allows setting the delay of an animation in progress: negative delay that'
|
|
+ ' seeks into the active interval');
|
|
|
|
promise_test(async t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(t, { fill: 'both', duration: 100 });
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ delay: -100 });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
|
|
}, 'Allows setting the delay of an animation in progress: large negative delay'
|
|
+ ' that causes the animation to be finished');
|
|
|
|
for (const invalid of gBadDelayValues) {
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t)
|
|
anim.play();
|
|
assert_throws_js(TypeError, () => {
|
|
anim.effect.updateTiming({ delay: invalid });
|
|
});
|
|
}, `Throws when setting invalid delay value: ${invalid}`);
|
|
}
|
|
|
|
|
|
// ------------------------------
|
|
// endDelay
|
|
// ------------------------------
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ endDelay: 123.45 });
|
|
assert_time_equals_literal(anim.effect.getTiming().endDelay, 123.45,
|
|
'set endDelay 123.45');
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().endDelay, 123.45,
|
|
'getComputedTiming() after set endDelay 123.45');
|
|
}, 'Allows setting the endDelay to a positive number');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ endDelay: -1000 });
|
|
assert_equals(anim.effect.getTiming().endDelay, -1000, 'set endDelay -1000');
|
|
assert_equals(anim.effect.getComputedTiming().endDelay, -1000,
|
|
'getComputedTiming() after set endDelay -1000');
|
|
}, 'Allows setting the endDelay to a negative number');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
await anim.ready;
|
|
assert_throws_js(TypeError, () => {
|
|
anim.effect.updateTiming({ endDelay: Infinity });
|
|
});
|
|
}, 'Throws when setting the endDelay to infinity');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
await anim.ready;
|
|
assert_throws_js(TypeError, () => {
|
|
anim.effect.updateTiming({ endDelay: -Infinity });
|
|
});
|
|
}, 'Throws when setting the endDelay to negative infinity');
|
|
|
|
|
|
// ------------------------------
|
|
// fill
|
|
// ------------------------------
|
|
|
|
for (const fill of ['none', 'forwards', 'backwards', 'both']) {
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 100 })
|
|
anim.play();
|
|
anim.effect.updateTiming({ fill });
|
|
assert_equals(anim.effect.getTiming().fill, fill, 'set fill ' + fill);
|
|
assert_equals(anim.effect.getComputedTiming().fill, fill,
|
|
'getComputedTiming() after set fill ' + fill);
|
|
}, `Allows setting the fill to '${fill}'`);
|
|
}
|
|
|
|
|
|
// ------------------------------
|
|
// iterationStart
|
|
// ------------------------------
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { iterationStart: 0.2,
|
|
iterations: 1,
|
|
fill: 'both',
|
|
duration: 100,
|
|
delay: 1 })
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ iterationStart: 2.5 });
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
|
}, 'Allows setting the iterationStart of an animation in progress:'
|
|
+ ' backwards-filling');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { iterationStart: 0.2,
|
|
iterations: 1,
|
|
fill: 'both',
|
|
duration: 100,
|
|
delay: 0 })
|
|
anim.play();
|
|
await anim.ready;
|
|
anim.effect.updateTiming({ iterationStart: 2.5 });
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 2);
|
|
}, 'Allows setting the iterationStart of an animation in progress:'
|
|
+ ' active phase');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { iterationStart: 0.3,
|
|
iterations: 1,
|
|
fill: 'both',
|
|
duration: 200,
|
|
delay: 0 })
|
|
anim.play();
|
|
await anim.ready;
|
|
assert_percents_equal(anim.currentTime, 0);
|
|
assert_percents_equal(anim.effect.getComputedTiming().localTime, 0,
|
|
"localTime");
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
|
|
|
|
anim.finish();
|
|
assert_percents_equal(anim.currentTime, 100);
|
|
assert_percents_equal(anim.effect.getComputedTiming().localTime, 100,
|
|
"localTime");
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.3);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 1);
|
|
|
|
anim.effect.updateTiming({ iterationStart: 2.5 });
|
|
assert_percents_equal(anim.currentTime, 100);
|
|
assert_percents_equal(anim.effect.getComputedTiming().localTime, 100,
|
|
"localTime");
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.5);
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 3);
|
|
}, 'Allows setting the iterationStart of an animation in progress:'
|
|
+ ' forwards-filling');
|
|
|
|
for (const invalid of gBadIterationStartValues) {
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t)
|
|
anim.play();
|
|
assert_throws_js(TypeError, () => {
|
|
anim.effect.updateTiming({ iterationStart: invalid });
|
|
}, `setting ${invalid}`);
|
|
}, `Throws when setting invalid iterationStart value: ${invalid}`);
|
|
}
|
|
|
|
// ------------------------------
|
|
// iterations
|
|
// ------------------------------
|
|
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
anim.effect.updateTiming({ iterations: 2 });
|
|
assert_equals(anim.effect.getTiming().iterations, 2, 'set duration 2');
|
|
assert_equals(anim.effect.getComputedTiming().iterations, 2,
|
|
'getComputedTiming() after set iterations 2');
|
|
}, 'Allows setting iterations to a double value');
|
|
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
assert_throws_js(TypeError, () => {
|
|
anim.effect.updateTiming({ iterations: Infinity });
|
|
}, "test");
|
|
}, `Throws when setting iterations to Infinity`);
|
|
|
|
|
|
// progress based animations behave a bit differently than time based animations
|
|
// when changing iterations.
|
|
test(t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(
|
|
t, { duration: 100000, fill: 'both' });
|
|
anim.play();
|
|
anim.finish();
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress when animation is finished');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 100,
|
|
'duration when animation is finished');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
|
'current iteration when animation is finished');
|
|
|
|
anim.effect.updateTiming({ iterations: 2 });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after adding an iteration');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 50,
|
|
'duration after adding an iteration');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
|
|
'current iteration after adding an iteration');
|
|
|
|
anim.effect.updateTiming({ iterations: 4 });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after setting iterations to 4');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 25,
|
|
'duration after setting iterations to 4');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 3,
|
|
'current iteration after setting iterations to 4');
|
|
|
|
anim.effect.updateTiming({ iterations: 0 });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
|
'progress after setting iterations to zero');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 0,
|
|
'duration after setting iterations to zero');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
|
'current iteration after setting iterations to zero');
|
|
}, 'Allows setting the iterations of an animation in progress');
|
|
|
|
// Added test for checking duration "auto"
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { fill: 'both' });
|
|
anim.play();
|
|
anim.finish();
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress when animation is finished');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 100,
|
|
'duration when animation is finished');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
|
'current iteration when animation is finished');
|
|
|
|
anim.effect.updateTiming({ iterations: 2 });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after adding an iteration');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 50,
|
|
'duration after adding an iteration');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 1,
|
|
'current iteration after adding an iteration');
|
|
|
|
anim.effect.updateTiming({ iterations: 4 });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after setting iterations to 4');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 25,
|
|
'duration after setting iterations to 4');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 3,
|
|
'current iteration after setting iterations to 4');
|
|
|
|
anim.effect.updateTiming({ iterations: 0 });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
|
'progress after setting iterations to zero');
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration, 0,
|
|
'duration after setting iterations to zero');
|
|
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
|
'current iteration after setting iterations to zero');
|
|
}, 'Allows setting the iterations of an animation in progress with duration ' +
|
|
'"auto"');
|
|
|
|
|
|
// ------------------------------
|
|
// duration
|
|
// ------------------------------
|
|
// adapted for progress based animations
|
|
const gGoodDurationValuesForProgressBased = [
|
|
// until duration returns a CSSNumberish which can handle percentages, 100%
|
|
// will be represented as 100
|
|
{ specified: 123.45, computed: 100 },
|
|
{ specified: 'auto', computed: 100 },
|
|
{ specified: Infinity, computed: 100 },
|
|
];
|
|
|
|
for (const duration of gGoodDurationValuesForProgressBased) {
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, 2000);
|
|
anim.play();
|
|
anim.effect.updateTiming({ duration: duration.specified });
|
|
if (typeof duration.specified === 'number') {
|
|
assert_time_equals_literal(anim.effect.getTiming().duration,
|
|
duration.specified,
|
|
'Updates specified duration');
|
|
} else {
|
|
assert_equals(anim.effect.getTiming().duration, duration.specified,
|
|
'Updates specified duration');
|
|
}
|
|
assert_percents_equal(anim.effect.getComputedTiming().duration,
|
|
duration.computed,
|
|
'Updates computed duration');
|
|
}, `Allows setting the duration to ${duration.specified}`);
|
|
}
|
|
|
|
// adapted for progress based animations
|
|
const gBadDurationValuesForProgressBased = [
|
|
-1, NaN, -Infinity, 'abc', '100'
|
|
];
|
|
|
|
for (const invalid of gBadDurationValuesForProgressBased) {
|
|
test(t => {
|
|
assert_throws_js(TypeError, () => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: invalid })
|
|
anim.play();
|
|
});
|
|
}, 'Throws when setting invalid duration: '
|
|
+ (typeof invalid === 'string' ? `"${invalid}"` : invalid));
|
|
}
|
|
|
|
test(t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(
|
|
t, { duration: 100000, fill: 'both' });
|
|
anim.play();
|
|
anim.finish();
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress when animation is finished');
|
|
anim.effect.updateTiming({ duration: anim.effect.getTiming().duration * 2 });
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after doubling the duration');
|
|
anim.effect.updateTiming({ duration: 0 });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after setting duration to zero');
|
|
anim.effect.updateTiming({ duration: 'auto' });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after setting duration to \'auto\'');
|
|
}, 'Allows setting the duration of an animation in progress');
|
|
|
|
promise_test(t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(
|
|
t, { duration: 100000, fill: 'both' });
|
|
anim.play();
|
|
return anim.ready.then(() => {
|
|
const originalStartTime = anim.startTime;
|
|
const originalCurrentTime = anim.currentTime;
|
|
assert_percents_equal(
|
|
anim.effect.getComputedTiming().duration,
|
|
100,
|
|
'Initial duration should be as set on KeyframeEffect'
|
|
);
|
|
|
|
anim.effect.updateTiming({ duration: 200000 });
|
|
assert_percents_equal(
|
|
anim.effect.getComputedTiming().duration,
|
|
100,
|
|
'Effect duration should remain at 100% for progress based animations'
|
|
);
|
|
assert_percents_equal(anim.startTime, originalStartTime,
|
|
'startTime should be unaffected by changing effect ' +
|
|
'duration');
|
|
|
|
assert_percents_equal(anim.currentTime, originalCurrentTime,
|
|
'currentTime should be unaffected by changing ' +
|
|
'effect duration');
|
|
});
|
|
}, 'Allows setting the duration of an animation in progress such that the' +
|
|
' the start and current time do not change');
|
|
|
|
|
|
// ------------------------------
|
|
// direction
|
|
// ------------------------------
|
|
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 2000 });
|
|
anim.play();
|
|
|
|
const directions = ['normal', 'reverse', 'alternate', 'alternate-reverse'];
|
|
for (const direction of directions) {
|
|
anim.effect.updateTiming({ direction: direction });
|
|
assert_equals(anim.effect.getTiming().direction, direction,
|
|
`set direction to ${direction}`);
|
|
}
|
|
}, 'Allows setting the direction to each of the possible keywords');
|
|
|
|
promise_test(async t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(
|
|
t, { duration: 10000, direction: 'normal' });
|
|
|
|
const scroller = anim.timeline.source;
|
|
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
|
|
anim.play();
|
|
await anim.ready;
|
|
scroller.scrollTop = maxScroll * 0.07
|
|
await waitForNextFrame();
|
|
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.07,
|
|
'progress before updating direction');
|
|
|
|
anim.effect.updateTiming({ direction: 'reverse' });
|
|
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.93,
|
|
'progress after updating direction');
|
|
}, 'Allows setting the direction of an animation in progress from \'normal\' ' +
|
|
'to \'reverse\'');
|
|
|
|
promise_test(async t => {
|
|
const anim =
|
|
createScrollLinkedAnimationWithTiming(
|
|
t, { duration: 10000, direction: 'normal' });
|
|
anim.play();
|
|
await anim.ready;
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
|
'progress before updating direction');
|
|
|
|
anim.effect.updateTiming({ direction: 'reverse' });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after updating direction');
|
|
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
|
+ ' \'reverse\' while at start of active interval');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { fill: 'backwards',
|
|
duration: 10000,
|
|
delay: 10000,
|
|
direction: 'normal' });
|
|
anim.play();
|
|
await anim.ready;
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
|
'progress before updating direction');
|
|
|
|
anim.effect.updateTiming({ direction: 'reverse' });
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'progress after updating direction');
|
|
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
|
+ ' \'reverse\' while filling backwards');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { iterations: 2,
|
|
duration: 10000,
|
|
direction: 'normal' });
|
|
const scroller = anim.timeline.source;
|
|
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
|
|
anim.play();
|
|
await anim.ready;
|
|
scroller.scrollTop = maxScroll * 0.17 // 34% through first iteration
|
|
await waitForNextFrame();
|
|
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.34,
|
|
'progress before updating direction');
|
|
|
|
anim.effect.updateTiming({ direction: 'alternate' });
|
|
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.34,
|
|
'progress after updating direction');
|
|
}, 'Allows setting the direction of an animation in progress from \'normal\' to'
|
|
+ ' \'alternate\'');
|
|
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { iterations: 2,
|
|
duration: 10000,
|
|
direction: 'alternate' });
|
|
const scroller = anim.timeline.source;
|
|
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
|
|
anim.play();
|
|
await anim.ready;
|
|
scroller.scrollTop = maxScroll * 0.17
|
|
await waitForNextFrame();
|
|
// anim.currentTime = 17000; // 34% through first iteration
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.34,
|
|
'progress before updating direction');
|
|
|
|
anim.effect.updateTiming({ direction: 'alternate-reverse' });
|
|
|
|
assert_time_equals_literal(anim.effect.getComputedTiming().progress, 0.66,
|
|
'progress after updating direction');
|
|
}, 'Allows setting the direction of an animation in progress from \'alternate\''
|
|
+ ' to \'alternate-reverse\'');
|
|
|
|
|
|
// ------------------------------
|
|
// easing
|
|
// ------------------------------
|
|
|
|
async function assert_progress(animation, scrollPercent, easingFunction) {
|
|
const scroller = animation.timeline.source;
|
|
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
|
|
scroller.scrollTop = maxScroll * scrollPercent
|
|
await waitForNextFrame();
|
|
assert_approx_equals(animation.effect.getComputedTiming().progress,
|
|
easingFunction(scrollPercent),
|
|
0.01,
|
|
'The progress of the animation should be approximately'
|
|
+ ` ${easingFunction(scrollPercent)} at ${scrollPercent}%`);
|
|
}
|
|
|
|
for (const options of gEasingTests) {
|
|
promise_test(async t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t, { duration: 100000,
|
|
fill: 'forwards' });
|
|
anim.play();
|
|
anim.effect.updateTiming({ easing: options.easing });
|
|
assert_equals(anim.effect.getTiming().easing,
|
|
options.serialization || options.easing);
|
|
|
|
const easing = options.easingFunction;
|
|
await assert_progress(anim, 0, easing);
|
|
await assert_progress(anim, 0.25, easing);
|
|
await assert_progress(anim, 0.5, easing);
|
|
await assert_progress(anim, 0.75, easing);
|
|
await assert_progress(anim, 1, easing);
|
|
}, `Allows setting the easing to a ${options.desc}`);
|
|
}
|
|
|
|
for (const easing of gRoundtripEasings) {
|
|
test(t => {
|
|
const anim = createScrollLinkedAnimationWithTiming(t);
|
|
anim.play();
|
|
anim.effect.updateTiming({ easing: easing });
|
|
assert_equals(anim.effect.getTiming().easing, easing);
|
|
}, `Updates the specified value when setting the easing to '${easing}'`);
|
|
}
|
|
|
|
// Because of the delay being so large, this progress based animation is always
|
|
// in the finished state with progress 1. Included here because it is in the
|
|
// original test file for time based animations.
|
|
promise_test(async t => {
|
|
const delay = 1000000;
|
|
|
|
const anim = createScrollLinkedAnimationWithTiming(t,
|
|
{ duration: 1000000, fill: 'both', delay: delay, easing: 'steps(2, start)' });
|
|
|
|
const scroller = anim.timeline.source;
|
|
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
|
|
anim.play();
|
|
await anim.ready;
|
|
|
|
anim.effect.updateTiming({ easing: 'steps(2, end)' });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0,
|
|
'easing replace to steps(2, end) at before phase');
|
|
|
|
scroller.scrollTop = maxScroll * 0.875
|
|
await waitForNextFrame();
|
|
|
|
assert_equals(anim.effect.getComputedTiming().progress, 0.5,
|
|
'change currentTime to active phase');
|
|
|
|
anim.effect.updateTiming({ easing: 'steps(2, start)' });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'easing replace to steps(2, start) at active phase');
|
|
|
|
scroller.scrollTop = maxScroll * 1.25
|
|
await waitForNextFrame();
|
|
|
|
anim.effect.updateTiming({ easing: 'steps(2, end)' });
|
|
assert_equals(anim.effect.getComputedTiming().progress, 1,
|
|
'easing replace to steps(2, end) again at after phase');
|
|
}, 'Allows setting the easing of an animation in progress');
|
|
</script>
|
|
</body>
|