87 lines
3 KiB
HTML
87 lines
3 KiB
HTML
<!DOCTYPE html>
|
|
<html id="top">
|
|
<meta charset="utf-8">
|
|
<title>View timeline animation events</title>
|
|
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#events">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/web-animations/testcommon.js"></script>
|
|
<style type="text/css">
|
|
@keyframes anim {
|
|
from { transform: translateX(0); }
|
|
to { transform: translateX(100px); }
|
|
}
|
|
#target {
|
|
background: green;
|
|
height: 100px;
|
|
width: 100px;
|
|
margin-bottom: 150vh;
|
|
animation-timeline: view();
|
|
}
|
|
.animate {
|
|
animation: anim auto;
|
|
}
|
|
</style>
|
|
<body>
|
|
<div id="target"></div>
|
|
</body>
|
|
<script type="text/javascript">
|
|
promise_test(async t => {
|
|
const target = document.getElementById('target');
|
|
|
|
// Create a timeline and advance to the next frame to ensure that the
|
|
// timeline has a value for currentTime.
|
|
await waitForNextFrame();
|
|
const timeline = new ViewTimeline({ subject: target });
|
|
await waitForNextFrame();
|
|
|
|
let animationstart_events = 0;
|
|
let animationend_events = 0;
|
|
document.addEventListener('animationstart', () => {
|
|
animationstart_events++;
|
|
});
|
|
document.addEventListener('animationend', () => {
|
|
animationend_events++;
|
|
});
|
|
|
|
// Start the animation and swap out its timeline while still play-pending
|
|
// so that it already has a value for current time.
|
|
target.classList.add('animate');
|
|
const anim = target.getAnimations();
|
|
anim.timeline = timeline;
|
|
// Introduce a style change that will make the timeline state stale when
|
|
// "ticked" at the start of the next animation frame.
|
|
target.style = 'margin-top: 150vh';
|
|
|
|
assert_false(!!anim.startTime,
|
|
'Start time deferred until timeline is updated');
|
|
|
|
// Verify that we are not evaluating a start time based on a stale timeline.
|
|
await waitForNextFrame();
|
|
await waitForNextFrame();
|
|
assert_equals(animationstart_events, 0,
|
|
'Target initially off-screen and no animationstart event');
|
|
assert_equals(animationend_events, 0,
|
|
'Target initially off-screen and no animationend event');
|
|
|
|
const scroller = document.scrollingElement;
|
|
scroller.scrollTop = target.getBoundingClientRect().top;
|
|
await waitForNextFrame();
|
|
await waitForNextFrame();
|
|
|
|
assert_equals(animationstart_events, 1,
|
|
'scrollstart event received after scrolling into view.');
|
|
assert_equals(animationend_events, 0,
|
|
"No scrollend event until after scrolling out of view");
|
|
|
|
scroller.scrollTop = target.getBoundingClientRect().bottom;
|
|
|
|
await waitForNextFrame();
|
|
await waitForNextFrame();
|
|
|
|
assert_equals(animationstart_events, 1,
|
|
'No additional scrollstart event');
|
|
assert_equals(animationend_events, 1,
|
|
'scrollend event received after scrolling out of view');
|
|
}, 'View timelime generates animationstart and animationend events');
|
|
</script>
|