|
49 | 49 | promise_test(async t => {
|
50 | 50 | const animation = createScrollLinkedWorkletAnimation(t);
|
51 | 51 | const scroller = animation.timeline.scrollSource;
|
| 52 | + const target = animation.effect.target; |
| 53 | + |
| 54 | + // There is no direct way to control when local times of composited |
| 55 | + // animations are synced to the main thread. This test uses another |
| 56 | + // composited worklet animation with an always active timeline as an |
| 57 | + // indicator of when the sync is ready. The sync is done when animation |
| 58 | + // effect's output has changed as a result of advancing the timeline. |
| 59 | + const animationRef = createScrollLinkedWorkletAnimation(t); |
| 60 | + const scrollerRef = animationRef.timeline.scrollSource; |
| 61 | + const targetRef = animationRef.effect.target; |
52 | 62 |
|
53 | 63 | const maxScroll = scroller.scrollHeight - scroller.clientHeight;
|
54 | 64 | const timeRange = animation.timeline.timeRange;
|
|
60 | 70 | scroller.scrollTop;
|
61 | 71 |
|
62 | 72 | animation.play();
|
| 73 | + animationRef.play(); |
63 | 74 | assert_equals(animation.currentTime, null,
|
64 | 75 | 'Initial current time must be unresolved in idle state.');
|
65 | 76 | assert_equals(animation.startTime, null,
|
|
72 | 83 | assert_equals(animation.startTime, null,
|
73 | 84 | 'Initial start time must be unresolved in playing state.');
|
74 | 85 |
|
| 86 | + scrollerRef.scrollTop = 0.2 * maxScroll; |
| 87 | + |
| 88 | + // Wait until local times are synced back to the main thread. |
| 89 | + await waitForAnimationFrameWithCondition(_ => { |
| 90 | + return animationRef.effect.getComputedTiming().localTime == 200; |
| 91 | + }); |
| 92 | + |
| 93 | + assert_equals(animation.effect.getComputedTiming().localTime, null, |
| 94 | + 'The underlying effect local time must be undefined while the ' + |
| 95 | + 'timeline is inactive.'); |
| 96 | + |
75 | 97 | // Make the timeline active.
|
76 | 98 | scroller.style.display = ""
|
77 | 99 | scroller.scrollTop;
|
|
81 | 103 | assert_times_equal(animation.startTime, 0,
|
82 | 104 | 'Start time must be initialized.');
|
83 | 105 |
|
| 106 | + scrollerRef.scrollTop = 0.4 * maxScroll; |
| 107 | + // Wait until local times are synced back to the main thread. |
| 108 | + await waitForAnimationFrameWithCondition(_ => { |
| 109 | + return animationRef.effect.getComputedTiming().localTime == 400; |
| 110 | + }); |
| 111 | + assert_times_equal(animation.effect.getComputedTiming().localTime, 200, |
| 112 | + 'When the timeline becomes newly active, the underlying effect\'s ' + |
| 113 | + 'timing should be properly updated.'); |
| 114 | + |
84 | 115 | // Make the timeline inactive again.
|
85 | 116 | scroller.style.display = "none"
|
86 | 117 | scroller.scrollTop;
|
|
90 | 121 | assert_equals(animation.startTime, null,
|
91 | 122 | 'Initial start time must be unresolved.');
|
92 | 123 |
|
| 124 | + scrollerRef.scrollTop = 0.6 * maxScroll; |
| 125 | + scrollerRef.scrollTop; |
| 126 | + // Wait until local times are synced back to the main thread. |
| 127 | + await waitForAnimationFrameWithCondition(_ => { |
| 128 | + return animationRef.effect.getComputedTiming().localTime == 600; |
| 129 | + }); |
| 130 | + |
| 131 | + assert_times_equal(animation.effect.getComputedTiming().localTime, 200, |
| 132 | + 'When the timeline becomes newly inactive, the underlying effect\'s ' + |
| 133 | + 'timing should stay unchanged.'); |
93 | 134 | }, 'When timeline time becomes inactive previous current time must be ' +
|
94 | 135 | 'the current time and start time unresolved');
|
95 | 136 | done();
|
|
0 commit comments