163 lines
6.2 KiB
HTML
163 lines
6.2 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<link rel="help" src="https://drafts.csswg.org/css-animations-2/#animation-trigger">
|
|
<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); }
|
|
to { transform: scaleX(5); }
|
|
}
|
|
.subject, .target {
|
|
height: 50px;
|
|
width: 50px;
|
|
background-color: red;
|
|
}
|
|
.target {
|
|
animation: myAnim linear 0.5s both;
|
|
animation-trigger: repeat;
|
|
animation-trigger-range: 250px 300px;
|
|
animation-trigger-exit-range: 200px 350px;
|
|
}
|
|
.scroll {
|
|
animation-trigger-timeline: scroll();
|
|
}
|
|
.view {
|
|
animation-trigger-timeline: view();
|
|
}
|
|
.deferred {
|
|
animation-trigger-timeline: --viewtimeline;
|
|
}
|
|
.deferred.subject {
|
|
view-timeline: --viewtimeline;
|
|
}
|
|
.scroller {
|
|
overflow-y: scroll;
|
|
height: 500px;
|
|
width: 500px;
|
|
border: solid 1px;
|
|
position: relative;
|
|
}
|
|
#wrapper {
|
|
timeline-scope: --viewtimeline;
|
|
}
|
|
#space {
|
|
width: 50px;
|
|
height: 600px;
|
|
}
|
|
</style>
|
|
<div id="wrapper">
|
|
<div id="scroll_scroller" class="scroller">
|
|
<div id="space"></div>
|
|
<div id="scroll_target" class="scroll subject target" tabindex="0"></div>
|
|
<div id="space"></div>
|
|
</div>
|
|
<div id="view_scroller" class="scroller">
|
|
<div id="space"></div>
|
|
<div id="view_target" class="view subject target" tabindex="0"></div>
|
|
<div id="space"></div>
|
|
</div>
|
|
<div id="deferred_scroller" class="scroller">
|
|
<div id="space"></div>
|
|
<div id="deferred_subject" class="deferred subject" tabindex="0"></div>
|
|
<div id="space"></div>
|
|
</div>
|
|
<div id="deferred_target" class="deferred target" tabindex="0"></div>
|
|
</div>
|
|
<script>
|
|
// // Each test case sets these.
|
|
// let scroller;
|
|
// let target;
|
|
|
|
async function testRepeatAnimationTrigger(test, rangeBoundaries) {
|
|
// Just short of the trigger range start, no trigger action expected.
|
|
await testAnimationTrigger(test, () => {
|
|
return rangeBoundaries.exitTriggerRangeAbove();
|
|
}, target, ["animationstart", "animationend"], [false, false]);
|
|
|
|
// This skips the trigger range and should not play the animation.
|
|
await testAnimationTrigger(test, () => {
|
|
return rangeBoundaries.exitTriggerRangeBelow();
|
|
}, target, ["animationstart", "animationend"], [false, false]);
|
|
|
|
// This enters the trigger range and should play the animation.
|
|
await testAnimationTrigger(test, () => {
|
|
return rangeBoundaries.enterTriggerRange();
|
|
}, target, ["animationstart", "animationend"], [true, true]);
|
|
|
|
// This is a repeat trigger, exiting the exit range resets the animation.
|
|
// We waited for an animationend event in the previous step so we won't
|
|
// see an animationcancel event here. But, by inspecting
|
|
// style.transform, we should see that the animation was reset.
|
|
await testAnimationTrigger(test, () => {
|
|
return rangeBoundaries.exitExitRangeAbove();
|
|
}, target, ["animationstart", "animationend", "animationcancel"],
|
|
[false, false, false]);
|
|
assert_equals(getComputedStyle(target).transform, "none");
|
|
|
|
// This is a repeat trigger, re-entering plays the animation.
|
|
await testAnimationTrigger(test, async () => {
|
|
// Enter the range.
|
|
await rangeBoundaries.enterTriggerRange();
|
|
await waitForAnimationFrames(5);
|
|
// Exit the range.
|
|
return rangeBoundaries.exitExitRangeBelow();
|
|
}, target, ["animationstart", "animationend", "animationcancel"],
|
|
[true, false, true]);
|
|
}
|
|
|
|
const CSS_TRIGGER_START_PX = 250;
|
|
const CSS_TRIGGER_END_PX = 300;
|
|
const CSS_EXIT_START_PX = 200;
|
|
const CSS_EXIT_END_PX = 350;
|
|
|
|
promise_test(async (test) => {
|
|
scroller = scroll_scroller;
|
|
target = scroll_target;
|
|
|
|
const rangeBoundaries = getRangeBoundariesForTest(CSS_TRIGGER_START_PX,
|
|
CSS_TRIGGER_END_PX,
|
|
CSS_EXIT_START_PX,
|
|
CSS_EXIT_END_PX,
|
|
scroller);
|
|
await testRepeatAnimationTrigger(test, rangeBoundaries);
|
|
}, "once animation triggered via scroll() timeline.");
|
|
|
|
promise_test(async (test) => {
|
|
scroller = view_scroller;
|
|
target = view_target;
|
|
|
|
const COVER_START_OFFSET = 100;
|
|
|
|
const rangeBoundaries = getRangeBoundariesForTest(
|
|
COVER_START_OFFSET + CSS_TRIGGER_START_PX,
|
|
COVER_START_OFFSET + CSS_TRIGGER_END_PX,
|
|
COVER_START_OFFSET + CSS_EXIT_START_PX,
|
|
COVER_START_OFFSET + CSS_EXIT_END_PX,
|
|
scroller);
|
|
await testRepeatAnimationTrigger(test, rangeBoundaries);
|
|
}, "once animation triggered via view() timeline.");
|
|
|
|
promise_test(async (test) => {
|
|
scroller = deferred_scroller;
|
|
target = deferred_target;
|
|
|
|
const COVER_START_OFFSET = 100;
|
|
|
|
const rangeBoundaries = getRangeBoundariesForTest(
|
|
COVER_START_OFFSET + CSS_TRIGGER_START_PX,
|
|
COVER_START_OFFSET + CSS_TRIGGER_END_PX,
|
|
COVER_START_OFFSET + CSS_EXIT_START_PX,
|
|
COVER_START_OFFSET + CSS_EXIT_END_PX,
|
|
scroller);
|
|
await testRepeatAnimationTrigger(test, rangeBoundaries);
|
|
}, "once animation triggered via deferred (view) timeline.");
|
|
</script>
|
|
</body>
|
|
</html>
|