summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/scroll-animations/scroll-timelines/scroll-animation-effect-fill-modes.tentative.html
blob: b9cc154676135656a06966f4c369acfa4f06903f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<!DOCTYPE html>
<meta charset=utf-8>
<title>Verify applied effect output for all fill modes in all timeline states: before start, at start, in range, at end, after end while using various effect delay values</title>
<meta name="timeout" content="long">
<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: hidden;
    height: 200px;
    width: 200px;
  }
  .contents {
    /* Make scroll range 1000 to simplify the math and avoid rounding errors */
    height: 1200px;
    width: 100%;
  }
</style>
<div id="log"></div>
<script>
  'use strict';

  test(t => {
    const effect = new KeyframeEffect(createDiv(t), { opacity: [0.3, 0.7] });
    const animation = new Animation(effect, createScrollTimeline(t));

    assert_equals(effect.getTiming().fill, "auto");
    assert_equals(effect.getComputedTiming().fill, "none");
  }, "Scroll based animation effect fill mode should return 'auto' for" +
     " getTiming() and should return 'none' for getComputedTiming().")

  /* All interesting transitions:
      before start delay
      at start delay
      within active phase
      at effect end
      after effect end

      test_case data structure:
      fill_mode: {
        scroll_percentage: ["state description", expected applied effect value]
      }
  */
  const test_cases = {
    "none": {
      0.10: ["before start delay", 1],
      0.25: ["at start delay", 0.3],
      0.50: ["at midpoint", 0.5],
      0.75: ["at effect end", 1],
      0.90: ["after effect end", 1]
    },
    "backwards": {
      0.10: ["before start delay", 0.3],
      0.25: ["at start delay", 0.3],
      0.50: ["at midpoint", 0.5],
      0.75: ["at effect end", 1],
      0.90: ["after effect end", 1]
    },
    "forwards": {
      0.10: ["before timeline start", 1],
      0.25: ["at timeline start", 0.3],
      0.50: ["in timeline range", 0.5],
      0.75: ["at timeline end", 0.7],
      0.90: ["after timeline end", 0.7]
    },
    "both": {
      0.10: ["before timeline start", 0.3],
      0.25: ["at timeline start", 0.3],
      0.50: ["in timeline range", 0.5],
      0.75: ["at timeline end", 0.7],
      0.90: ["after timeline end", 0.7]
    },
    "auto": {
      0.10: ["before timeline start", 1],
      0.25: ["at timeline start", 0.3],
      0.50: ["in timeline range", 0.5],
      0.75: ["at timeline end", 1],
      0.90: ["after timeline end", 1]
    }
  }

  for (const fill_mode in test_cases) {
    const scroll_percents = test_cases[fill_mode]

    for (const scroll_percentage in scroll_percents) {
      const expectation = scroll_percents[scroll_percentage];

      const [test_name, expected_value] = expectation;

      const description =
          `Applied effect value ${test_name} with fill: ${fill_mode}`
      promise_test(
          create_scroll_timeline_fill_test(
              fill_mode, scroll_percentage, expected_value),
          description);
    }
  }

  function create_scroll_timeline_fill_test(
      fill_mode, scroll_percentage, expected){
    return async t => {
      const target = createDiv(t);

      const timeline = createScrollTimeline(t);
      const effect =
          new KeyframeEffect(target,
                             { opacity: [0.3, 0.7] },
                             {
                               fill: fill_mode,
                               /* Animation times normalized to fill scroll
                                  range */
                               duration: 2000,
                               delay: 1000,
                               endDelay: 1000
                             });
      const animation = new Animation(effect, timeline);
      const scroller = timeline.source;
      const maxScroll = scroller.scrollHeight - scroller.clientHeight;

      animation.play();

      await animation.ready;

      scroller.scrollTop = scroll_percentage * maxScroll;

      // Wait for new animation frame which allows the timeline to compute
      // new current time.
      await waitForNextFrame();

      assert_equals(parseFloat(window.getComputedStyle(target).opacity),
                    expected,
                    "animation effect applied property value");
    }
  }
</script>