Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 4 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /web-animations/interfaces/Animation/scroll-timeline-overallProgress.tentative.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<meta charset=utf-8>
<title>Animation.overallProgress</title>
<link rel="help"
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<script src="../../../scroll-animations/scroll-timelines/testcommon.js"></script>
<body>
<style>
.scroller {
overflow-x: hidden;
overflow-y: auto;
height: 200px;
width: 100px;
will-change: transform;
}
.contents {
height: 1200px;
width: 100%;
}
#target {
height: 100px;
width: 100px;
background-color: green;
margin-top: -1000px;
}
</style>
<div id="log"></div>
<script>
'use strict';
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
assert_equals(animation.currentTime, null,
"The current time is null in Idle state.");
assert_equals(animation.overallProgress, null,
"The overallProgress is null since the currentTime is unresolved.");
animation.play();
assert_true(animation.pending, "Animation is in the pending state.");
assert_equals(animation.currentTime, null,
"The current time remains null while in the pending state.");
assert_equals(animation.overallProgress, null,
"The overallProgress is null since the currentTime is unresolved.");
await animation.ready;
// Verify initial start and current times once ready.
assert_percents_equal(animation.currentTime, 0,
"The current time is resolved when ready.");
assert_equals(animation.overallProgress, 0,
"The overallProgress should be zero.");
scroller.scrollTop = 0.4 * maxScroll;
await waitForNextFrame();
assert_percents_equal(animation.currentTime, 40,
"currentTime reflects overallProgress as a percentage");
assert_approx_equals(animation.overallProgress, 0.4, 0.01,
"The overallProgress should match the scroll progress.");
}, "animation.overallProgress reflects the progress of a scroll animation as " +
"a number between 0 and 1");
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.source;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
animation.play();
await animation.ready;
// Verify initial start and current times once ready.
assert_percents_equal(animation.currentTime, 0,
"The current time is resolved when ready.");
assert_equals(animation.overallProgress, 0,
"The overallProgress should be zero.");
scroller.scrollTop = 0.4 * maxScroll;
await waitForNextFrame();
let timing = animation.effect.getComputedTiming();
// iteration duration should be 100%, overallProgress should reflect 40%.
assert_percents_equal(timing.duration, 100);
assert_percents_equal(animation.currentTime, 40,
"currentTime reflects progress as a percentage");
assert_approx_equals(animation.overallProgress, 0.4, 0.01,
"The overallProgress should match the scroll progress.");
timing = animation.effect.getComputedTiming();
animation.effect.updateTiming({ iterations: 2 });
timing = animation.effect.getComputedTiming();
// iteration duration should be 50%, overallProgress should still reflect 40%
// as it measures currentTime / effect endTime.
assert_percents_equal(timing.duration, 50);
assert_percents_equal(animation.currentTime, 40,
"currentTime reflects progress as a percentage");
assert_approx_equals(animation.overallProgress, 0.4, 0.01,
"The overallProgress is should match the scroll progress.");
}, "animation.overallProgress reflects the overall progress of a scroll " +
"with multiple iterations.");
promise_test(async t => {
const scroller = createScroller(t);
const view_timeline = createViewTimeline(t);
const animation = createAnimation(t);
animation.rangeStart = { rangeName: 'contain', offset: CSS.percent(10) };
animation.rangeEnd = { rangeName: 'contain', offset: CSS.percent(90) };
animation.timeline = view_timeline;
await animation.ready;
// Cover range is [0, 300]
// Contain range is [100, 200]
// rangeStart offset of 10% => 110px
// rangeEnd offset of 90% => 190px
const target_pct = 40;
const target_scroll_top = 110 + (target_pct / 100) * (190 - 110);
scroller.scrollTop = target_scroll_top;
await waitForNextFrame();
const start_time = 110 / 300 * 100;
const timeline_time = target_scroll_top / 300 * 100;
const expected_current_time = timeline_time - start_time;
assert_percents_equal(animation.currentTime, expected_current_time,
"currentTime reflects progress as a percentage");
assert_approx_equals(animation.overallProgress, target_pct / 100, 0.01,
"overallProgress should reflect fraction of view timeline range scroll "
+ "through.");
}, "animation.overallProgress reflects the overall progress of a scroll "
+ "that uses a view-timeline.");
promise_test(async t => {
const scroller = createScroller(t);
const view_timeline = createViewTimeline(t);
const animation = createAnimation(t);
animation.rangeStart = { rangeName: 'contain', offset: CSS.percent(10) };
animation.rangeEnd = { rangeName: 'contain', offset: CSS.percent(90) };
animation.timeline = view_timeline;
await animation.ready;
// Cover range is [0, 300]
// Contain range is [100, 200]
// rangeStart offset of 10% => 110px
// rangeEnd offset of 10% => 190px
scroller.scrollTop = 100;
await waitForNextFrame();
let timing = animation.effect.getComputedTiming();
assert_less_than(animation.currentTime.value, 0, "currentTime is negative");
assert_approx_equals(animation.overallProgress, 0, 0.01, "overallProgress " +
"is zero when scroll offset is less than range start.");
scroller.scrollTop = 200;
await waitForNextFrame();
assert_approx_equals(animation.currentTime.value, timing.endTime.value, 0.01,
"currentTime has reached endTime");
assert_approx_equals(animation.overallProgress, 1, 0.01, "overallProgress " +
"is one when scroll offset goes past than range end.");
}, "overallProgress of a view-timeline is bounded between 0 and 1.");
</script>
</body>