169 lines
No EOL
6 KiB
HTML
169 lines
No EOL
6 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="/css/css-typed-om/resources/testhelper.js"></script>
|
|
</head>
|
|
<body>
|
|
<style>
|
|
@keyframes myAnim {
|
|
from { transform: scaleX(1); }
|
|
to { transform: scaleX(5); }
|
|
}
|
|
.subject, .target {
|
|
height: 50px;
|
|
width: 50px;
|
|
background-color: red;
|
|
}
|
|
.subject {
|
|
view-timeline: --viewtimeline;
|
|
}
|
|
.target {
|
|
animation: myAnim linear 0.5s forwards;
|
|
}
|
|
#scroll_target {
|
|
animation-trigger: repeat scroll(inline) 150px 200px 100px 250px;
|
|
}
|
|
#view_target {
|
|
animation-trigger: state view(x) contain 10% contain 90% cover 10% cover 90%;
|
|
}
|
|
#deferred_target {
|
|
animation-trigger: alternate --viewtimeline contain 5% contain 80% cover 5% cover 80%;
|
|
}
|
|
.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="default_target" class="target"></div>
|
|
<div id="scroller" class="scroller">
|
|
<div id="space"></div>
|
|
<div id="scroll_target" class="target"></div>
|
|
<div id="space"></div>
|
|
<div id="view_target" class="target"></div>
|
|
<div id="space"></div>
|
|
<div id="deferred_subject" class="subject"></div>
|
|
<div id="space"></div>
|
|
</div>
|
|
<div id="deferred_target" class="target"></div>
|
|
</div>
|
|
<script>
|
|
function assert_timeline_offset(actual, expected, errorMessage) {
|
|
assert_equals(actual.rangeName, expected.rangeName, errorMessage);
|
|
assert_style_value_equals(actual.offset, expected.offset);
|
|
}
|
|
|
|
function testTrigger(trigger, expectation) {
|
|
assert_equals(trigger.type, expectation.type, "trigger type matches");
|
|
assert_timeline_offset(trigger.rangeStart, expectation.rangeStart,
|
|
"trigger rangeStart matches");
|
|
assert_timeline_offset(trigger.rangeEnd, expectation.rangeEnd,
|
|
"trigger rangeEnd matches");
|
|
assert_timeline_offset(trigger.exitRangeStart, expectation.exitRangeStart,
|
|
"trigger exitRangeStart matches");
|
|
assert_timeline_offset(trigger.exitRangeEnd, expectation.exitRangeEnd,
|
|
"trigger exitRangeEnd matches");
|
|
if (expectation.timeline === document.timeline) {
|
|
assert_equals(trigger.timeline, document.timeline, "timeline matches");
|
|
} else {
|
|
assert_equals(trigger.timeline.source, expectation.timelineSource,
|
|
"trigger timeline source matches");
|
|
assert_equals(trigger.timeline.axis, expectation.timelineAxis,
|
|
"trigger timeline axis matches");
|
|
assert_equals(trigger.timeline.subject, expectation.timelineSubject,
|
|
"trigger timeline subject matches");
|
|
}
|
|
}
|
|
|
|
promise_test(async() => {
|
|
await waitForNextFrame();
|
|
const animation = default_target.getAnimations()[0];
|
|
const trigger = animation.trigger;
|
|
|
|
const expectation = {
|
|
type: "once",
|
|
rangeStart: "normal",
|
|
rangeEnd: "normal",
|
|
exitRangeStart: "normal",
|
|
exitRangeEnd: "normal",
|
|
timeline: document.timeline
|
|
};
|
|
|
|
testTrigger(trigger, expectation);
|
|
}, "Default AnimationTrigger for CSS Animation");
|
|
|
|
promise_test(async() => {
|
|
await waitForNextFrame();
|
|
const animation = scroll_target.getAnimations()[0];
|
|
const trigger = animation.trigger;
|
|
await waitForNextFrame();
|
|
|
|
const expectation = {
|
|
type: "repeat",
|
|
rangeStart: { rangeName: "none", offset: CSS.px(150) },
|
|
rangeEnd: { rangeName: "none", offset: CSS.px(200) },
|
|
exitRangeStart: { rangeName: "none", offset: CSS.px(100) },
|
|
exitRangeEnd: { rangeName: "none", offset: CSS.px(250) },
|
|
timelineSource: scroller,
|
|
timelineAxis: "inline"
|
|
};
|
|
|
|
testTrigger(trigger, expectation);
|
|
}, "AnimationTrigger for CSS Animation with scroll() timeline");
|
|
|
|
promise_test(async() => {
|
|
await waitForNextFrame();
|
|
const animation = view_target.getAnimations()[0];
|
|
const trigger = animation.trigger;
|
|
await waitForNextFrame();
|
|
|
|
const expectation = {
|
|
type: "state",
|
|
rangeStart: { rangeName: 'contain', offset: CSS.percent(10) },
|
|
rangeEnd: { rangeName: 'contain', offset: CSS.percent(90) },
|
|
exitRangeStart: { rangeName: 'cover', offset: CSS.percent(10) },
|
|
exitRangeEnd: { rangeName: 'cover', offset: CSS.percent(90) },
|
|
timelineSource: scroller,
|
|
timelineAxis: "x",
|
|
timelineSubject: view_target
|
|
};
|
|
|
|
testTrigger(trigger, expectation);
|
|
}, "AnimationTrigger for CSS Animation with view() timeline");
|
|
|
|
promise_test(async() => {
|
|
await waitForNextFrame();
|
|
const animation = deferred_target.getAnimations()[0];
|
|
const trigger = animation.trigger;
|
|
await waitForNextFrame();
|
|
|
|
const expectation = {
|
|
type: "alternate",
|
|
rangeStart: { rangeName: 'contain', offset: CSS.percent(5) },
|
|
rangeEnd: { rangeName: 'contain', offset: CSS.percent(80) },
|
|
exitRangeStart: { rangeName: 'cover', offset: CSS.percent(5) },
|
|
exitRangeEnd: { rangeName: 'cover', offset: CSS.percent(80) },
|
|
timelineSource: scroller,
|
|
timelineAxis: "block",
|
|
timelineSubject: deferred_subject
|
|
};
|
|
|
|
testTrigger(trigger, expectation);
|
|
}, "AnimationTrigger for CSS Animation with deferred timeline");
|
|
</script>
|
|
</body>
|
|
</html> |