Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="/dom/events/scrolling/scroll_support.js"></script>
<script src="support/support.js"></script>
</head>
<body>
<style>
@keyframes myAnim {
from { transform: scaleX(1); left: 0px }
to { transform: scaleX(5); left: 10px }
}
.subject, .target {
height: 50px;
width: 50px;
background-color: red;
}
.scroller {
overflow-y: scroll;
height: 500px;
width: 500px;
border: solid 1px;
position: relative;
}
#space {
width: 50px;
height: 600px;
}
</style>
<div id="wrapper">
<div id="scroller" class="scroller">
<div id="space"></div>
<div id="subject" class="subject"></div>
<div id="space"></div>
</div>
<div id="target" class="target"></div>
</div>
<script>
// The trigger and exit ranges are the same for this test.
const TRIGGER_START_PX = 150;
const TRIGGER_END_PX = 200;
const scroller = document.getElementById("scroller");
const target = document.getElementById("target");
const COVER_START_OFFSET = 100;
const rangeBoundaries = getRangeBoundariesForTest(
COVER_START_OFFSET + TRIGGER_START_PX,
COVER_START_OFFSET + TRIGGER_END_PX,
COVER_START_OFFSET + TRIGGER_START_PX,
COVER_START_OFFSET + TRIGGER_END_PX,
scroller);
const ANIMATION_DURATION_MS = 1;
function watchAnimationStatus(animation, targetCurrentTime,
targetPlayState, resolve, repeat=2) {
if (repeat <= 0) {
resolve();
return;
}
if (targetCurrentTime === null) {
assert_equals(animation.currentTime, targetCurrentTime,
"currentTime has not changed.");
} else {
assert_times_equal(animation.currentTime, targetCurrentTime, 1,
"currentTime has not changed.");
}
assert_equals(animation.playState, targetPlayState,
"playState has not changed.");
requestAnimationFrame(() => {
watchAnimationStatus(animation, targetCurrentTime, targetPlayState,
resolve, repeat - 1);
});
}
const view_timeline = new ViewTimeline({ subject: subject });
function setupAnimation() {
const animation = new Animation(
new KeyframeEffect(
target,
[
{ transform: "scaleX(1)", backgroundColor: "pink", left: "0px" },
{ transform: "scaleX(5)", backgroundColor: "pink", left: "10px" }
],
{ duration: ANIMATION_DURATION_MS, fill: "both" }
));
return animation;
}
function setupAnimationTrigger(use_default_trigger=false) {
const trigger = new AnimationTrigger({
behavior: "alternate",
timeline: view_timeline,
rangeStart: `${TRIGGER_START_PX}px`,
rangeEnd: `${TRIGGER_END_PX}px`
});
return trigger;
}
promise_test(async(test) => {
const animation = setupAnimation();
const trigger = setupAnimationTrigger();
assert_equals(animation.currentTime, null,
"animation is idle; null currentTime.");
assert_equals(animation.playState, "idle", "animation is idle.");
// Attaching the trigger should simply keep the animaiton paused at
// zero currentTime.
trigger.addAnimation(animation);
await waitForNextFrame();
assert_times_equal(animation.currentTime, 0,
"animation is paused at currentTime zero.");
assert_equals(animation.playState, "paused", "animation is paused.");
// First, verify that the trigger is indeed active.
await rangeBoundaries.enterTriggerRange();
await animation.finished;
assert_times_equal(animation.currentTime, ANIMATION_DURATION_MS,
"animation finished (currentTime)");
assert_equals(animation.playState, "finished",
"animation finished (playState)");
animation.cancel();
// Ensure exiting does nothing.
status_promise = new Promise(resolve => {
watchAnimationStatus(animation, null, "idle", resolve);
});
await rangeBoundaries.exitExitRangeAbove();
await status_promise;
// Ensure re-entering does nothing.
status_promise = new Promise(resolve => {
watchAnimationStatus(animation, null, "idle", resolve);
});
await rangeBoundaries.enterTriggerRange();
await status_promise;
}, "cancel disables animation trigger");
</script>
</body>
</html>