summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/web-animations/timing-model/animation-effects/phases-and-states.html
blob: 5dc32066fea78e935850ee3617250216f15ac82d (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<!doctype html>
<meta charset=utf-8>
<title>Tests for phases and states</title>
<link rel="help" href="https://w3c.github.io/web-animations/#animation-effect-phases-and-states">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';

// --------------------------------------------------------------------
//
// Phases
//
// --------------------------------------------------------------------

function assert_phase_at_time(animation, phase, currentTime) {
  animation.currentTime = currentTime;

  if (phase === 'active') {
    // If the fill mode is 'none', then progress will only be non-null if we
    // are in the active phase.
    animation.effect.timing.fill = 'none';
    assert_not_equals(animation.effect.getComputedTiming().progress, null,
                      'Animation effect is in active phase when current time'
                      + ' is ' + currentTime + 'ms');
  } else {
    // The easiest way to distinguish between the 'before' phase and the 'after'
    // phase is to toggle the fill mode. For example, if the progress is null
    // will the fill node is 'none' but non-null when the fill mode is
    // 'backwards' then we are in the before phase.
    animation.effect.timing.fill = 'none';
    assert_equals(animation.effect.getComputedTiming().progress, null,
                  'Animation effect is in ' + phase + ' phase when current time'
                  + ' is ' + currentTime + 'ms'
                  + ' (progress is null with \'none\' fill mode)');

    animation.effect.timing.fill = phase === 'before'
                                   ? 'backwards'
                                   : 'forwards';
    assert_not_equals(animation.effect.getComputedTiming().progress, null,
                      'Animation effect is in ' + phase + ' phase when current'
                      + ' time is ' + currentTime + 'ms'
                      + ' (progress is non-null with appropriate fill mode)');
  }
}

test(function(t) {
  var animation = createDiv(t).animate(null, 1);

  [ { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'active' },
    { currentTime:  1, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for a simple animation effect');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1, delay: 1 });

  [ { currentTime: 0, phase: 'before' },
    { currentTime: 1, phase: 'active' },
    { currentTime: 2, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a positive start delay');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1, delay: -1 });

  [ { currentTime: -2, phase: 'before' },
    { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a negative start delay');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1, endDelay: 1 });

  [ { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'active' },
    { currentTime:  1, phase: 'after'  },
    { currentTime:  2, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a positive end delay');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 2, endDelay: -1 });

  [ { currentTime: -1,   phase: 'before' },
    { currentTime:  0,   phase: 'active' },
    { currentTime:  0.9, phase: 'active' },
    { currentTime:  1,   phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a negative end delay lesser'
   + ' in magnitude than the active duration');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1, endDelay: -1 });

  [ { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'after'  },
    { currentTime:  1, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a negative end delay equal'
   + ' in magnitude to the active duration');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1, endDelay: -2 });

  [ { currentTime: -2, phase: 'before' },
    { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a negative end delay'
   + ' greater in magnitude than the active duration');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 2,
                                               delay: 1,
                                               endDelay: -1 });

  [ { currentTime: 0, phase: 'before' },
    { currentTime: 1, phase: 'active' },
    { currentTime: 2, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a positive start delay'
   + ' and a negative end delay lesser in magnitude than the active duration');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1,
                                               delay: -1,
                                               endDelay: -1 });

  [ { currentTime: -2, phase: 'before' },
    { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a negative start delay'
   + ' and a negative end delay equal in magnitude to the active duration');

test(function(t) {
  var animation = createDiv(t).animate(null, { duration: 1,
                                               delay: -1,
                                               endDelay: -2 });

  [ { currentTime: -3, phase: 'before' },
    { currentTime: -2, phase: 'before' },
    { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for an animation effect with a negative start delay'
   + ' and a negative end delay equal greater in magnitude than the active'
   + ' duration');

test(function(t) {
  var animation = createDiv(t).animate(null, 1);
  animation.playbackRate = -1;

  [ { currentTime: -1, phase: 'before' },
    { currentTime:  0, phase: 'before' },
    { currentTime:  1, phase: 'active' },
    { currentTime:  2, phase: 'after'  } ]
  .forEach(function(test) {
    assert_phase_at_time(animation, test.phase, test.currentTime);
  });
}, 'Phase calculation for a simple animation effect with negative playback'
   + ' rate');

</script>
</body>