1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
<!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>
|