| <!DOCTYPE html> | |
| <meta charset=utf-8> | |
| <title>Test basic functionality of scroll linked animation.</title> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="/web-animations/testcommon.js"></script> | |
| <script src="testcommon.js"></script> | |
| <style> | |
| .scroller { | |
| overflow: auto; | |
| height: 100px; | |
| width: 100px; | |
| will-change: transform; | |
| } | |
| .contents { | |
| height: 1000px; | |
| width: 100%; | |
| } | |
| </style> | |
| <div id="log"></div> | |
| <script> | |
| 'use strict'; | |
| promise_test(async t => { | |
| const animation = createScrollLinkedAnimation(t); | |
| const scroller = animation.timeline.source; | |
| const maxScroll = scroller.scrollHeight - scroller.clientHeight; | |
| // Wait for new animation frame which allows the timeline to compute new | |
| // current time. | |
| await waitForNextFrame(); | |
| // Verify initial start and current times in Idle state. | |
| assert_equals(animation.currentTime, null, | |
| "The current time is null in Idle state."); | |
| assert_equals(animation.startTime, null, | |
| "The start time is null in Idle state."); | |
| animation.play(); | |
| assert_true(animation.pending, "Animation is in pending state."); | |
| // Verify initial start and current times in Pending state. | |
| assert_percents_equal(animation.currentTime, 0, | |
| "The current time is zero in Pending state."); | |
| assert_percents_equal(animation.startTime, 0, | |
| "The start time is zero in Pending state."); | |
| await animation.ready; | |
| // Verify initial start and current times in Playing state. | |
| assert_percents_equal(animation.currentTime, 0, | |
| "The current time is zero in Playing state."); | |
| assert_percents_equal(animation.startTime, 0, | |
| "The start time is zero in Playing state."); | |
| // Now do some scrolling and make sure that the Animation current time is | |
| // correct. | |
| scroller.scrollTop = 0.4 * maxScroll; | |
| // Wait for new animation frame which allows the timeline to compute new | |
| // current time. | |
| await waitForNextFrame(); | |
| assert_percents_equal(animation.currentTime, animation.timeline.currentTime, | |
| "The current time corresponds to the scroll position of the scroller."); | |
| assert_times_equal( | |
| animation.effect.getComputedTiming().progress, | |
| // Division by 100 is temporary, it will be removed when progress returns | |
| // a CSSNumericValue instead of a double 0-1 | |
| animation.timeline.currentTime.value / 100, | |
| 'Effect progress corresponds to the scroll position of the scroller.'); | |
| }, 'Animation start and current times are correct for each animation state.'); | |
| promise_test(async t => { | |
| const animation = createScrollLinkedAnimation(t); | |
| const scroller = animation.timeline.source; | |
| const maxScroll = scroller.scrollHeight - scroller.clientHeight; | |
| // Advance the scroller. | |
| scroller.scrollTop = 0.2 * maxScroll; | |
| // Wait for new animation frame which allows the timeline to compute new | |
| // current time. | |
| await waitForNextFrame(); | |
| // Verify initial start and current times in Idle state. | |
| assert_equals(animation.currentTime, null, | |
| "The current time is null in Idle state."); | |
| assert_equals(animation.startTime, null, | |
| "The start time is null in Idle state."); | |
| animation.play(); | |
| // Verify initial start and current times in Pending state. | |
| assert_percents_equal(animation.currentTime, animation.timeline.currentTime, | |
| "The current time is a hold time in Pending state."); | |
| assert_percents_equal(animation.startTime, 0, | |
| "The start time is zero in Pending state."); | |
| await animation.ready; | |
| // Verify initial start and current times in Playing state. | |
| assert_percents_equal(animation.currentTime, animation.timeline.currentTime, | |
| "The current corresponds to the scroll position of the scroller."); | |
| assert_percents_equal(animation.startTime, 0, | |
| "The start time is zero in Playing state."); | |
| }, 'Animation start and current times are correct for each animation state' + | |
| ' when the animation starts playing with advanced scroller.'); | |
| promise_test(async t => { | |
| const timeline = createScrollTimeline(t); | |
| const animation1 = createScrollLinkedAnimation(t, timeline); | |
| const animation2 = createScrollLinkedAnimation(t, timeline); | |
| const scroller = timeline.source; | |
| const maxScroll = scroller.scrollHeight - scroller.clientHeight; | |
| // Advance the scroller. | |
| scroller.scrollTop = 0.4 * maxScroll; | |
| // Wait for new animation frame which allows the timeline to compute new | |
| // current time. | |
| await waitForNextFrame(); | |
| // Verify initial start and current times in Idle state. | |
| assert_equals(animation1.currentTime, null, | |
| "The current time is null in Idle state."); | |
| assert_equals(animation1.startTime, null, | |
| "The start time is null in Idle state."); | |
| assert_equals(animation2.currentTime, null, | |
| "The current time is null in Idle state."); | |
| assert_equals(animation2.startTime, null, | |
| "The start time is null in Idle state."); | |
| animation1.play(); | |
| animation2.play(); | |
| // Verify initial start and current times in Pending state. | |
| assert_percents_equal(animation1.currentTime, timeline.currentTime, | |
| "The current time corresponds to the scroll position of the scroller" + | |
| " in Pending state."); | |
| assert_percents_equal(animation1.startTime, 0, | |
| "The start time is zero in Pending state."); | |
| assert_percents_equal(animation2.currentTime, timeline.currentTime, | |
| "The current time corresponds to the scroll position of the scroller" + | |
| " in Pending state."); | |
| assert_percents_equal(animation2.startTime, 0, | |
| "The start time is zero in Pending state."); | |
| await animation1.ready; | |
| await animation2.ready; | |
| // Verify initial start and current times in Playing state. | |
| assert_percents_equal(animation1.currentTime, timeline.currentTime, | |
| "The current corresponds to the scroll position of the scroller."); | |
| assert_percents_equal(animation1.startTime, 0, | |
| "The start time is zero in Playing state."); | |
| assert_percents_equal(animation2.currentTime, timeline.currentTime, | |
| "The current corresponds to the scroll position of the scroller."); | |
| assert_percents_equal(animation2.startTime, 0, | |
| "The start time is zero in Playing state."); | |
| }, 'Animation start and current times are correct when multiple animations' + | |
| ' are attached to the same timeline.'); | |
| promise_test(async t => { | |
| const animation = createScrollLinkedAnimation(t); | |
| const scroller = animation.timeline.source; | |
| const maxScroll = scroller.scrollHeight - scroller.clientHeight; | |
| animation.play(); | |
| await animation.ready; | |
| // Advance the scroller to max position. | |
| scroller.scrollTop = maxScroll; | |
| await animation.finished; | |
| assert_equals(animation.playState, 'finished', | |
| 'Animation state is in finished state.'); | |
| assert_percents_equal(animation.currentTime, 100, | |
| 'Animation current time is at 100% on reverse scrolling.'); | |
| // Scroll back. | |
| scroller.scrollTop = 0.2 * maxScroll; | |
| // Wait for new animation frame which allows the timeline to compute new | |
| // current time. | |
| await waitForNextFrame(); | |
| // Verify animation state and current time on reverse scrolling. | |
| assert_equals(animation.playState, 'running', | |
| 'Animation state is playing on reverse scrolling.'); | |
| assert_percents_equal(animation.currentTime, 20, | |
| 'Animation current time is updated on reverse scrolling.'); | |
| }, 'Finished animation plays on reverse scrolling.'); | |
| promise_test(async t => { | |
| const animation = createScrollLinkedAnimation(t); | |
| const scroller = animation.timeline.source; | |
| const maxScroll = scroller.scrollHeight - scroller.clientHeight; | |
| animation.play(); | |
| await animation.ready; | |
| // Advance the scroller to max position. | |
| scroller.scrollTop = maxScroll; | |
| await animation.finished; | |
| var sent_finish_event = false; | |
| animation.onfinish = function() { | |
| sent_finish_event = true; | |
| }; | |
| // Scroll back. | |
| scroller.scrollTop = 0.2 * maxScroll; | |
| // Wait for new animation frame which allows the timeline to compute new | |
| // current time. | |
| await waitForNextFrame(); | |
| assert_false(sent_finish_event, | |
| "No animation finished event is sent on reverse scroll."); | |
| scroller.scrollTop = maxScroll; | |
| await animation.finished; | |
| // Wait for next frame to allow the animation to send finish events. The | |
| // finished promise fires before events are sent. | |
| await waitForNextFrame(); | |
| assert_true(sent_finish_event, | |
| "Animation finished event is sent on reaching max scroll."); | |
| }, 'Sending animation finished events by finished animation on reverse ' + | |
| 'scrolling.'); | |
| </script> |