| <!DOCTYPE html> |
| <title>Animations using view-timeline</title> |
| <link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#view-timelines-named"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/web-animations/testcommon.js"></script> |
| <script src="support/testcommon.js"></script> |
| <style> |
| @keyframes anim { |
| from { z-index: 0; } |
| to { z-index: 100; } |
| } |
| .vertical-scroller { |
| overflow: auto; |
| width: 100px; |
| height: 100px; |
| } |
| .vertical-scroller > div { |
| height: 50px; |
| z-index: -1; |
| } |
| .horizontal-scroller { |
| overflow: auto; |
| width: 100px; |
| height: 100px; |
| writing-mode: vertical-lr; |
| } |
| .horizontal-scroller > div { |
| width: 50px; |
| z-index: -1; |
| } |
| </style> |
| <main id=main></main> |
| <script> |
| setup(assert_implements_animation_timeline); |
| |
| 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 scrollLeft(e, value) { |
| e.scrollLeft = value; |
| await waitForNextFrame(); |
| } |
| </script> |
| |
| <template id=default_view_timeline> |
| <style> |
| #target { |
| view-timeline: t1; |
| animation: anim 1s linear; |
| animation-timeline: t1; |
| } |
| </style> |
| <div id=scroller class=vertical-scroller> |
| <div></div> <!-- [0px, 50px] --> |
| <div></div> <!-- [50px, 100px] --> |
| <div></div> <!-- [100px, 150px] --> |
| <div id=target></div> <!-- [150px, 200px] --> |
| <div></div> <!-- [200px, 250px] --> |
| <div></div> <!-- [250px, 300px] --> |
| <div></div> <!-- [300px, 350px] --> |
| </div> |
| </template> |
| <script> |
| promise_test(async (t) => { |
| inflate(t, default_view_timeline); |
| assert_equals(getComputedStyle(target).zIndex, '-1'); |
| await scrollTop(scroller, 25); |
| assert_equals(getComputedStyle(target).zIndex, '-1'); |
| await scrollTop(scroller, 50); // 0% (enter 0%) |
| assert_equals(getComputedStyle(target).zIndex, '0'); |
| await scrollTop(scroller, 125); // 50% |
| assert_equals(getComputedStyle(target).zIndex, '50'); |
| await scrollTop(scroller, 200); // 100% (exit 100%) |
| assert_equals(getComputedStyle(target).zIndex, '100'); |
| await scrollTop(scroller, 225); |
| assert_equals(getComputedStyle(target).zIndex, '-1'); |
| }, 'Default view-timeline'); |
| </script> |
| |
| <template id=horizontal_timeline> |
| <style> |
| #target { |
| view-timeline: t1 horizontal; |
| animation: anim 1s linear; |
| animation-timeline: t1; |
| } |
| </style> |
| <div id=scroller class=horizontal-scroller> |
| <div></div> <!-- [0px, 50px] --> |
| <div></div> <!-- [50px, 100px] --> |
| <div></div> <!-- [100px, 150px] --> |
| <div id=target></div> <!-- [150px, 200px] --> |
| <div></div> <!-- [200px, 250px] --> |
| <div></div> <!-- [250px, 300px] --> |
| <div></div> <!-- [300px, 350px] --> |
| </div> |
| </template> |
| <script> |
| promise_test(async (t) => { |
| inflate(t, horizontal_timeline); |
| assert_equals(getComputedStyle(target).zIndex, '-1'); |
| await scrollLeft(scroller, 25); |
| assert_equals(getComputedStyle(target).zIndex, '-1'); |
| await scrollLeft(scroller, 50); // 0% (enter 0%) |
| assert_equals(getComputedStyle(target).zIndex, '0'); |
| await scrollLeft(scroller, 125); // 50% |
| assert_equals(getComputedStyle(target).zIndex, '50'); |
| await scrollLeft(scroller, 200); // 100% (exit 100%) |
| assert_equals(getComputedStyle(target).zIndex, '100'); |
| await scrollLeft(scroller, 225); |
| assert_equals(getComputedStyle(target).zIndex, '-1'); |
| }, 'Horizontal view-timeline'); |
| </script> |
| |
| <template id=multiple_timelines> |
| <style> |
| #timelines { |
| view-timeline: tv vertical, th horizontal; |
| background-color: red; |
| } |
| #scroller { |
| width: 100px; |
| height: 100px; |
| overflow: hidden; |
| display: grid; |
| grid-template-columns: 50px 50px 50px 50px 50px 50px 50px; |
| grid-template-row: 50px 50px 50px 50px 50px 50px 50px; |
| } |
| #scroller > div { |
| z-index: -1; |
| width: 50px; |
| height: 50px; |
| } |
| #target_v { |
| animation: anim 1s linear; |
| animation-timeline: tv; |
| } |
| #target_h { |
| animation: anim 1s linear; |
| animation-timeline: th; |
| } |
| </style> |
| <div id=scroller> |
| <!-- Created dynamically --> |
| </div> |
| </template> |
| <script> |
| promise_test(async (t) => { |
| inflate(t, multiple_timelines); |
| |
| // Create a 350px x 350px grid (7x7 items of 50x50px each), with the |
| // timelines at item [3,3], an element attached to the horizontal timeline |
| // at [4,3], and an element attached to the vertical timeline at [3,4]. |
| |
| // x x x x x x x |
| // x x x x x x x |
| // x x x x x x x |
| // x x x T H x x |
| // x x x V x x x |
| // x x x x x x x |
| // x x x x x x x |
| // x x x x x x x |
| |
| let grid_size = 7; |
| for (let i = 0; i < (grid_size*grid_size); ++i) { |
| let div = document.createElement('div'); |
| if (i == (3 * grid_size + 3)) |
| div.id = 'timelines'; |
| if (i == (3 * grid_size + 4)) |
| div.id = 'target_h'; |
| if (i == (4 * grid_size + 3)) |
| div.id = 'target_v'; |
| scroller.append(div); |
| } |
| |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| |
| // First scroll vertically. |
| await scrollTop(scroller, 25); |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| await scrollTop(scroller, 50); // 0% (enter 0%) |
| assert_equals(getComputedStyle(target_v).zIndex, '0'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| await scrollTop(scroller, 125); // 50% |
| assert_equals(getComputedStyle(target_v).zIndex, '50'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| await scrollTop(scroller, 200); // 100% (exit 100%) |
| assert_equals(getComputedStyle(target_v).zIndex, '100'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| await scrollTop(scroller, 225); |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| |
| // Then horizontally. |
| await scrollLeft(scroller, 25); |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| await scrollLeft(scroller, 50); // 0% (enter 0%) |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '0'); |
| await scrollLeft(scroller, 125); // 50% |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '50'); |
| await scrollLeft(scroller, 200); // 100% (exit 100%) |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '100'); |
| await scrollLeft(scroller, 225); |
| assert_equals(getComputedStyle(target_v).zIndex, '-1'); |
| assert_equals(getComputedStyle(target_h).zIndex, '-1'); |
| }, 'Multiple view-timelines on the same element'); |
| </script> |