OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <script src="../resources/testharness.js"></script> | |
3 <script src="../resources/testharnessreport.js"></script> | |
4 | |
5 <style> | |
6 .anim { | |
7 position: absolute; | |
8 left: 10px; | |
9 height: 90px; | |
10 width: 100px; | |
11 background-color: black; | |
12 } | |
13 </style> | |
14 | |
15 <body> | |
16 </body> | |
17 | |
18 <script> | |
19 var addAnimDiv = function() { | |
20 var element = document.createElement('div'); | |
21 element.className = 'anim'; | |
22 document.body.appendChild(element); | |
23 return element; | |
24 }; | |
25 | |
26 var assertEquivalentFramesSyntax = function(testParams) { | |
27 var e1 = addAnimDiv(); | |
28 var e2 = addAnimDiv(); | |
29 var e1Style = getComputedStyle(e1); | |
30 var e2Style = getComputedStyle(e2); | |
31 var options = {duration: testParams.duration, fill: "forwards"}; | |
32 var player1 = e1.animate(testParams.listOfKeyframes, options); | |
33 var player2 = e2.animate(testParams.keyframeWithListOfValues, options); | |
34 player1.pause(); | |
35 player2.pause(); | |
36 for (var i = 0; i < testParams.expectationList.length; i++) { | |
37 var expected = testParams.expectationList[i]; | |
38 player1.currentTime = expected.at; | |
39 player2.currentTime = expected.at; | |
40 for (var property in expected.is) { | |
41 assert_equals(e1Style.getPropertyValue(property), expected.is[proper
ty]); | |
42 assert_equals(e2Style.getPropertyValue(property), expected.is[proper
ty]); | |
43 } | |
44 } | |
45 }; | |
46 | |
47 test(function() { | |
48 var element = addAnimDiv(); | |
49 var elementStyle = getComputedStyle(element); | |
50 var player = element.animate([ | |
51 {left: '10px', opacity: '1', offset: 0}, | |
52 {left: '100px', opacity: '0', offset: 1} | |
53 ], 1); | |
54 player.pause(); | |
55 player.currentTime = 0.5; | |
56 assert_equals(elementStyle.left, '55px'); | |
57 assert_equals(elementStyle.opacity, '0.5'); | |
58 }, 'Calling animate() should start an animation.'); | |
59 | |
60 test(function() { | |
61 assertEquivalentFramesSyntax({ | |
62 listOfKeyframes: [ | |
63 {left: '10px', opacity: '1'}, | |
64 {left: '100px', opacity: '0'}, | |
65 {left: '150px', opacity: '1'} | |
66 ], | |
67 keyframeWithListOfValues: { | |
68 left: ['10px', '100px', '150px'], | |
69 opacity: ['1', '0', '1'] | |
70 }, | |
71 duration: 1, | |
72 expectationList: [ | |
73 {at: 0, is: {left: '10px', opacity: '1'}}, | |
74 {at: 0.25, is: {left: '55px', opacity: '0.5'}}, | |
75 {at: 0.5, is: {left: '100px', opacity: '0'}}, | |
76 {at: 0.75, is: {left: '125px', opacity: '0.5'}}, | |
77 {at: 1, is: {left: '150px', opacity: '1'}} | |
78 ] | |
79 }); | |
80 }, 'Calling animate() with alternative list syntax should give same result.'); | |
81 | |
82 test(function() { | |
83 var element = addAnimDiv(); | |
84 var elementStyle = getComputedStyle(element); | |
85 var player = element.animate([ | |
86 {backgroundColor: 'green', offset: 0}, | |
87 {backgroundColor: 'purple', offset: 1} | |
88 ], 1); | |
89 player.pause(); | |
90 player.currentTime = 0.5; | |
91 assert_equals(elementStyle.backgroundColor, 'rgb(64, 64, 64)'); | |
92 }, 'Calling animate() should start an animation. CamelCase property names should
be parsed.'); | |
93 | |
94 test(function() { | |
95 var element = addAnimDiv(); | |
96 var elementStyle = getComputedStyle(element); | |
97 var player = element.animate([ | |
98 {left: '10px', offset: '0'}, | |
99 {left: '100px', offset: '1'} | |
100 ], 1); | |
101 player.pause(); | |
102 player.currentTime = 0.5; | |
103 assert_equals(elementStyle.left, '55px'); | |
104 }, 'Offsets may be specified as strings.'); | |
105 | |
106 test(function() { | |
107 assertEquivalentFramesSyntax({ | |
108 listOfKeyframes: [ | |
109 {left: '0px', easing: 'steps(2, start)'}, | |
110 {left: '100px', easing: 'steps(2, start)'}, | |
111 {left: '300px'} | |
112 ], | |
113 keyframeWithListOfValues: { | |
114 left: ['0px', '100px', '300px'], | |
115 easing: 'steps(2, start)' | |
116 }, | |
117 duration: 1, | |
118 expectationList: [ | |
119 {at: 0, is: {left: '50px'}}, | |
120 {at: 0.25, is: {left: '100px'}}, | |
121 {at: 0.5, is: {left: '200px'}}, | |
122 {at: 0.75, is: {left: '300px'}} | |
123 ] | |
124 }); | |
125 }, 'When using the alternative list syntax, all keyframes have the same timing f
unction.'); | |
126 | |
127 test(function() { | |
128 assertEquivalentFramesSyntax({ | |
129 listOfKeyframes: [ | |
130 {left: '0px', offset: 0.5}, | |
131 {left: '100px', offset: 0.5} | |
132 ], | |
133 keyframeWithListOfValues: { | |
134 left: ['0px', '100px'], | |
135 offset: 0.5 | |
136 }, | |
137 duration: 1, | |
138 expectationList: [ | |
139 {at: 0, is: {left: '10px'}}, | |
140 {at: 0.25, is: {left: '5px'}}, | |
141 {at: 0.49, is: {left: '0.2px'}}, | |
142 {at: 0.5, is: {left: '100px'}}, | |
143 {at: 0.75, is: {left: '55px'}}, | |
144 {at: 1, is: {left: '10px'}} | |
145 ] | |
146 }); | |
147 }, 'When using the alternative list syntax, offset is applied to all specified k
eyframes.'); | |
148 | |
149 test(function() { | |
150 assertEquivalentFramesSyntax({ | |
151 listOfKeyframes: [ | |
152 {left: '0px', composite: 'add'}, | |
153 {left: '100px', composite: 'add'} | |
154 ], | |
155 keyframeWithListOfValues: { | |
156 left: ['0px', '100px'], | |
157 composite: 'add' | |
158 }, | |
159 duration: 1, | |
160 expectationList: [ | |
161 {at: 0, is: {left: '10px'}}, | |
162 {at: 0.5, is: {left: '60px'}}, | |
163 {at: 1, is: {left: '110px'}} | |
164 ] | |
165 }); | |
166 }, 'When using the alternative list syntax, composite is applied to all keyframe
s.'); | |
167 | |
168 test(function() { | |
169 assertEquivalentFramesSyntax({ | |
170 listOfKeyframes: [ | |
171 {left: '0px', offset: 0}, | |
172 {opacity: '0', offset: 0}, | |
173 {left: '10px', offset: 0.33}, | |
174 {opacity: '0.4', offset: 0.5}, | |
175 {left: '40px', offset: 0.67}, | |
176 {left: '100px', offset: 1}, | |
177 {opacity: '1', offset: 1} | |
178 ], | |
179 keyframeWithListOfValues: { | |
180 left: ['0px', '10px', '40px', '100px'], | |
181 opacity: ['0', '0.4', '1'] | |
182 }, | |
183 duration: 1, | |
184 expectationList: [ | |
185 {at: 0, is: {left: '0px', opacity: '0'}}, | |
186 {at: 0.5, is: {left: '25px', opacity: '0.4'}}, | |
187 {at: 1, is: {left: '100px', opacity: '1'}} | |
188 ] | |
189 }); | |
190 }, 'When using the alternative list syntax, properties can have different length
lists.'); | |
191 | |
192 test(function() { | |
193 assertEquivalentFramesSyntax({ | |
194 listOfKeyframes: [ | |
195 {left: '100px'} | |
196 ], | |
197 keyframeWithListOfValues: { | |
198 left: ['100px'] | |
199 }, | |
200 duration: 1, | |
201 expectationList: [ | |
202 {at: 0, is: {left: '10px'}}, | |
203 {at: 0.5, is: {left: '55px'}}, | |
204 {at: 1, is: {left: '100px'}} | |
205 ] | |
206 }); | |
207 assertEquivalentFramesSyntax({ | |
208 listOfKeyframes: [ | |
209 {left: '100px'} | |
210 ], | |
211 keyframeWithListOfValues: { | |
212 left: '100px' | |
213 }, | |
214 duration: 1, | |
215 expectationList: [ | |
216 {at: 0, is: {left: '10px'}}, | |
217 {at: 0.5, is: {left: '55px'}}, | |
218 {at: 1, is: {left: '100px'}} | |
219 ] | |
220 }); | |
221 }, 'The list of keyframes can have one element.'); | |
222 | |
223 test(function() { | |
224 var element = addAnimDiv(); | |
225 var keyframes = [ | |
226 {left: ['10px', '100px']}, | |
227 {left: ['5px', '50px']} | |
228 ]; | |
229 assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1
); }); | |
230 }, 'Should throw when mixing two different list syntaxes.'); | |
231 | |
232 test(function() { | |
233 var element = addAnimDiv(); | |
234 var keyframes = [ | |
235 {opacity: '0.5', offset: 0.5}, | |
236 {opacity: '0.9', offset: 1}, | |
237 {opacity: '0', offset: 0} | |
238 ]; | |
239 assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1
); }); | |
240 }, 'Should throw when keyframes have unsorted offsets.'); | |
241 | |
242 test(function() { | |
243 var element = addAnimDiv(); | |
244 var keyframes = [ | |
245 {opacity: '1', offset: -1}, | |
246 {opacity: '1', offset: NaN}, | |
247 {opacity: '1', offset: 2}, | |
248 {opacity: '0.5', offset: 1}, | |
249 {opacity: '0', offset: 0} | |
250 ]; | |
251 assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1
); }); | |
252 }, 'Should throw when keyframes has offsets outside the range [0.0, 1.0].'); | |
253 | |
254 test(function() { | |
255 var element = addAnimDiv(); | |
256 var keyframes = [ | |
257 {opacity: '0.5'}, | |
258 {opacity: '1', offset: 1}, | |
259 {opacity: '0', offset: 0} | |
260 ]; | |
261 assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1
); }); | |
262 }, 'Should throw when keyframes are not loosely sorted and any have no offset.')
; | |
263 | |
264 test(function() { | |
265 var element = addAnimDiv(); | |
266 var keyframes = [ | |
267 {opacity: '0.5', offset: null}, | |
268 {opacity: '1', offset: 1}, | |
269 {opacity: '0', offset: 0} | |
270 ]; | |
271 assert_throws({name: 'TypeError'}, function() { element.animate(keyframes, 1
); }); | |
272 }, 'Should throw when keyframes are not loosely sorted and any have null offset.
'); | |
273 | |
274 var keyframesWithInvalid = [ | |
275 {width: '0px', backgroundColor: 'octarine', offset: 0}, | |
276 {width: '1000px', foo: 'bar', offset: 1}]; | |
277 | |
278 test(function() { | |
279 var element = addAnimDiv(); | |
280 var elementStyle = getComputedStyle(element); | |
281 var player = element.animate(keyframesWithInvalid, {duration: 1, fill: 'forw
ards'}); | |
282 player.pause(); | |
283 player.currentTime = 1; | |
284 assert_equals(elementStyle.width, '1000px'); | |
285 assert_equals(elementStyle.backgroundColor, 'rgb(0, 0, 0)'); | |
286 assert_equals(elementStyle.foo, undefined); | |
287 }, 'Calling animate() with a pre-constructed keyframes list should start an anim
ation. Invalid style declarations should be ignored.'); | |
288 | |
289 </script> | |
OLD | NEW |