Skip to content

Commit

Permalink
[scroll-animations] Implement animation-delay-[start,end]
Browse files Browse the repository at this point in the history
This CL implements support for the animation-delay-start and -end
longhands, alongside the existing animation-delay longhand.

Animations that use non-default timelines will automatically use
the delays specified by animation-delay-[start,end], and other
animations will continue to use the start delay specified by
animation-delay.

Making animation-delay a shorthand based on a runtime flag is a bit
complicated since our code generation does not support it. That work
is therefore deferred to a later CL.

Bug: 1317765, 1375994
Change-Id: Iac5944876162557bb99942cc300489b8362e147a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3961415
Commit-Queue: Kevin Ellis <[email protected]>
Auto-Submit: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Kevin Ellis <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1063064}
  • Loading branch information
andruud authored and chromium-wpt-export-bot committed Oct 24, 2022
1 parent 884f8d2 commit 8f0a96c
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 0 deletions.
23 changes: 23 additions & 0 deletions css/css-animations/parsing/animation-delay-end-computed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#propdef-animation-delay-start">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
<div id="target"></div>
<script>
test_computed_value("animation-delay-start", "initial", "0s");
test_computed_value("animation-delay-start", "-500ms", "-0.5s");
test_computed_value("animation-delay-start", "calc(2 * 3s)", "6s");
test_computed_value("animation-delay-start", "20s, 10s");

test_computed_value("animation-delay-start", "cover 0%");
test_computed_value("animation-delay-start", "COVER 0%", "cover 0%");
test_computed_value("animation-delay-start", "cover 100%");
test_computed_value("animation-delay-start", "cover 120%");
test_computed_value("animation-delay-start", "cover 42%");
test_computed_value("animation-delay-start", "cover -42%");
test_computed_value("animation-delay-start", "contain 42%");
test_computed_value("animation-delay-start", "exit 42%");
test_computed_value("animation-delay-start", "exit calc(41% + 1%)", "exit 42%");
test_computed_value("animation-delay-start", "exit 1%, cover 2%, contain 100%");
</script>
29 changes: 29 additions & 0 deletions css/css-animations/parsing/animation-delay-end-invalid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#propdef-animation-delay-start">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
test_invalid_value("animation-delay-start", "infinite");
test_invalid_value("animation-delay-start", "0");
test_invalid_value("animation-delay-start", "1s 2s");
test_invalid_value("animation-delay-start", "1s / 2s");
test_invalid_value("animation-delay-start", "100px");
test_invalid_value("animation-delay-start", "100%");

test_invalid_value("animation-delay-start", "peek 50%");
test_invalid_value("animation-delay-start", "50% contain");
test_invalid_value("animation-delay-start", "50% cover");
test_invalid_value("animation-delay-start", "50% entry");
test_invalid_value("animation-delay-start", "50% enter");
test_invalid_value("animation-delay-start", "50% exit");
test_invalid_value("animation-delay-start", "contain contain");
test_invalid_value("animation-delay-start", "auto");
test_invalid_value("animation-delay-start", "none");
test_invalid_value("animation-delay-start", "cover 50% enter 50%");
test_invalid_value("animation-delay-start", "cover 100px");
test_invalid_value("animation-delay-start", "cover");
test_invalid_value("animation-delay-start", "contain");
test_invalid_value("animation-delay-start", "enter");
test_invalid_value("animation-delay-start", "exit");
</script>
26 changes: 26 additions & 0 deletions css/css-animations/parsing/animation-delay-end-valid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#propdef-animation-delay-start">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
test_valid_value("animation-delay-start", "-5ms");
test_valid_value("animation-delay-start", "0s");
test_valid_value("animation-delay-start", "10s");
test_valid_value("animation-delay-start", "20s, 10s");

// https://drafts.csswg.org/scroll-animations-1/#view-timelines-ranges
test_valid_value("animation-delay-start", "cover 0%");
test_valid_value("animation-delay-start", "cover 100%");
test_valid_value("animation-delay-start", "cover 120%");
test_valid_value("animation-delay-start", "cover 42%");
test_valid_value("animation-delay-start", "cover -42%");
test_valid_value("animation-delay-start", "contain 42%");
test_valid_value("animation-delay-start", "exit 42%");
test_valid_value("animation-delay-start", "exit 1%, cover 2%, contain 100%");

// There's an open issue in the spec about "enter" vs "entry".
//
// https://drafts.csswg.org/scroll-animations-1/#valdef-animation-timeline-range-entry
test_valid_value("animation-delay-start", "enter 42%");
</script>
23 changes: 23 additions & 0 deletions css/css-animations/parsing/animation-delay-start-computed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#propdef-animation-delay-start">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
<div id="target"></div>
<script>
test_computed_value("animation-delay-start", "initial", "0s");
test_computed_value("animation-delay-start", "-500ms", "-0.5s");
test_computed_value("animation-delay-start", "calc(2 * 3s)", "6s");
test_computed_value("animation-delay-start", "20s, 10s");

test_computed_value("animation-delay-start", "cover 0%");
test_computed_value("animation-delay-start", "COVER 0%", "cover 0%");
test_computed_value("animation-delay-start", "cover 100%");
test_computed_value("animation-delay-start", "cover 120%");
test_computed_value("animation-delay-start", "cover 42%");
test_computed_value("animation-delay-start", "cover -42%");
test_computed_value("animation-delay-start", "contain 42%");
test_computed_value("animation-delay-start", "exit 42%");
test_computed_value("animation-delay-start", "exit calc(41% + 1%)", "exit 42%");
test_computed_value("animation-delay-start", "exit 1%, cover 2%, contain 100%");
</script>
29 changes: 29 additions & 0 deletions css/css-animations/parsing/animation-delay-start-invalid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#propdef-animation-delay-start">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
test_invalid_value("animation-delay-start", "infinite");
test_invalid_value("animation-delay-start", "0");
test_invalid_value("animation-delay-start", "1s 2s");
test_invalid_value("animation-delay-start", "1s / 2s");
test_invalid_value("animation-delay-start", "100px");
test_invalid_value("animation-delay-start", "100%");

test_invalid_value("animation-delay-start", "peek 50%");
test_invalid_value("animation-delay-start", "50% contain");
test_invalid_value("animation-delay-start", "50% cover");
test_invalid_value("animation-delay-start", "50% entry");
test_invalid_value("animation-delay-start", "50% enter");
test_invalid_value("animation-delay-start", "50% exit");
test_invalid_value("animation-delay-start", "contain contain");
test_invalid_value("animation-delay-start", "auto");
test_invalid_value("animation-delay-start", "none");
test_invalid_value("animation-delay-start", "cover 50% enter 50%");
test_invalid_value("animation-delay-start", "cover 100px");
test_invalid_value("animation-delay-start", "cover");
test_invalid_value("animation-delay-start", "contain");
test_invalid_value("animation-delay-start", "enter");
test_invalid_value("animation-delay-start", "exit");
</script>
26 changes: 26 additions & 0 deletions css/css-animations/parsing/animation-delay-start-valid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#propdef-animation-delay-start">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
test_valid_value("animation-delay-start", "-5ms");
test_valid_value("animation-delay-start", "0s");
test_valid_value("animation-delay-start", "10s");
test_valid_value("animation-delay-start", "20s, 10s");

// https://drafts.csswg.org/scroll-animations-1/#view-timelines-ranges
test_valid_value("animation-delay-start", "cover 0%");
test_valid_value("animation-delay-start", "cover 100%");
test_valid_value("animation-delay-start", "cover 120%");
test_valid_value("animation-delay-start", "cover 42%");
test_valid_value("animation-delay-start", "cover -42%");
test_valid_value("animation-delay-start", "contain 42%");
test_valid_value("animation-delay-start", "exit 42%");
test_valid_value("animation-delay-start", "exit 1%, cover 2%, contain 100%");

// There's an open issue in the spec about "enter" vs "entry".
//
// https://drafts.csswg.org/scroll-animations-1/#valdef-animation-timeline-range-entry
test_valid_value("animation-delay-start", "enter 42%");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@

// Let animation be in before phase.
target.style.animationDelay = '10s';
target.style.animationDelayStart = '10s'; // crbug.com/1375994
assert_equals(getComputedStyle(target).translate, 'none');

await scrollTop(scroller, 50); // The animation enters active phase.
Expand All @@ -220,6 +221,7 @@

await scrollTop(scroller, 20); // [0, 100].
target.style.animationDelay = '-5s';
target.style.animationDelayStart = '-5s'; // crbug.com/1375994
await waitForCSSScrollTimelineStyle();
assert_equals(getComputedStyle(target).translate, '60px');
}, 'animation-delay with a negative value');
Expand All @@ -233,6 +235,7 @@
let [target, scroller] = createTargetAndScroller(t);
target.style.animation = '10s linear anim scroll(nearest)';
target.style.animationDelay = '10s';
target.style.animationDelayStart = '10s'; // crbug.com/1375994

await scrollTop(scroller, 25);
assert_equals(getComputedStyle(target).translate, 'none');
Expand Down
140 changes: 140 additions & 0 deletions scroll-animations/css/view-timeline-delay-animation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<!DOCTYPE html>
<title>Animations using named timeline ranges</title>
<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#named-timeline-range">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<style>
@keyframes anim {
from { z-index: 0; background-color: skyblue;}
to { z-index: 100; background-color: coral; }
}
#scroller {
border: 10px solid lightgray;
overflow-y: scroll;
width: 200px;
height: 200px;
}
#target {
margin: 800px 0px;
width: 100px;
height: 100px;
z-index: -1;
background-color: green;
}
</style>
<main id=main>
</main>
<template>
<div id=scroller>
<div id=target></div>
</div>
</template>
<script>
function inflate(t, template) {
t.add_cleanup(() => main.replaceChildren());
main.append(template.content.cloneNode(true));
}
async function scrollTop(e, value) {
e.scrollTop = value;
await waitForNextFrame();
}
async function waitForAnimationReady(target) {
await waitForNextFrame();
await Promise.all(target.getAnimations().map(x => x.promise));
}
async function assertValueAt(scroller, target, args) {
await waitForAnimationReady(target);
await scrollTop(scroller, args.scrollTop);
assert_equals(getComputedStyle(target).zIndex, args.expected.toString());
}
function test_animation_delay(options) {
promise_test(async (t) => {
inflate(t, document.querySelector('template'));
let scroller = main.querySelector('#scroller');
let target = main.querySelector('#target');

target.style.viewTimeline = 't1 block';
// TODO(crbug.com/1375998): Create the timeline in a separate frame to
// work around a bug.
await waitForNextFrame();

target.style.animation = 'anim 10s linear t1';
target.style.animationDelayStart = options.startDelay;
target.style.animationDelayEnd = options.endDelay;

// Accommodates floating point precision errors at the endpoints.
target.style.animationFillMode = 'both';

// 0%
await assertValueAt(scroller, target,
{ scrollTop: options.rangeStart, expected: 0 });
// 50%
await assertValueAt(scroller, target,
{ scrollTop: (options.rangeStart + options.rangeEnd) / 2, expected: 50 });
// 100%
await assertValueAt(scroller, target,
{ scrollTop: options.rangeEnd, expected: 100 });

// Test before/after phases (need to clear the fill mode for that).
target.style.animationFillMode = 'initial';
await assertValueAt(scroller, target,
{ scrollTop: options.rangeStart - 10, expected: -1 });
await assertValueAt(scroller, target,
{ scrollTop: options.rangeEnd + 10, expected: -1 });
// Check 50% again without fill mode.
await assertValueAt(scroller, target,
{ scrollTop: (options.rangeStart + options.rangeEnd) / 2, expected: 50 });

}, `Animation with delays [${options.startDelay}, ${options.endDelay}]`);
}

test_animation_delay({
startDelay: 'initial',
endDelay: 'initial',
rangeStart: 600,
rangeEnd: 900
});

test_animation_delay({
startDelay: 'cover 0%',
endDelay: 'cover 100%',
rangeStart: 600,
rangeEnd: 900
});

test_animation_delay({
startDelay: 'contain 0%',
endDelay: 'contain 100%',
rangeStart: 700,
rangeEnd: 800
});

test_animation_delay({
startDelay: 'enter 0%',
endDelay: 'enter 100%',
rangeStart: 600,
rangeEnd: 700
});

test_animation_delay({
startDelay: 'exit 0%',
endDelay: 'exit 100%',
rangeStart: 800,
rangeEnd: 900
});

test_animation_delay({
startDelay: 'contain -50%',
endDelay: 'enter 200%',
rangeStart: 650,
rangeEnd: 800
});

test_animation_delay({
startDelay: 'enter 0%',
endDelay: 'exit 100%',
rangeStart: 600,
rangeEnd: 900
});
</script>

0 comments on commit 8f0a96c

Please sign in to comment.