OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <meta charset=utf-8> | |
3 <title>Effect-level easing tests</title> | |
4 <link rel="help" href="http://w3c.github.io/web-animations/#calculating-the-tran
sformed-time"> | |
5 <link rel="author" title="Hiroyuki Ikezoe" href="mailto:hiikezoe@mozilla-japan.o
rg"> | |
6 <script src="../../../../resources/testharness.js"></script> | |
7 <script src="../../../../resources/testharnessreport.js"></script> | |
8 <script src="../testcommon.js"></script> | |
9 <body> | |
10 <div id="log"></div> | |
11 <div id="target"></div> | |
12 <script> | |
13 "use strict"; | |
14 | |
15 function assert_style_left_at(animation, time, easingFunction) { | |
16 animation.currentTime = time; | |
17 var portion = time / animation.effect.timing.duration; | |
18 assert_approx_equals(pxToNum(getComputedStyle(animation.effect.target).left), | |
19 easingFunction(portion) * 100, | |
20 0.01, | |
21 'The left of the animation should be approximately ' + | |
22 easingFunction(portion) * 100 + ' at ' + time + 'ms'); | |
23 } | |
24 | |
25 var gEffectEasingTests = [ | |
26 { | |
27 desc: 'steps(start) function', | |
28 easing: 'steps(2, start)', | |
29 easingFunction: stepStart(2) | |
30 }, | |
31 { | |
32 desc: 'steps(end) function', | |
33 easing: 'steps(2, end)', | |
34 easingFunction: stepEnd(2) | |
35 }, | |
36 { | |
37 desc: 'linear function', | |
38 easing: 'linear', // cubic-bezier(0, 0, 1.0, 1.0) | |
39 easingFunction: cubicBezier(0, 0, 1.0, 1.0) | |
40 }, | |
41 { | |
42 desc: 'ease function', | |
43 easing: 'ease', // cubic-bezier(0.25, 0.1, 0.25, 1.0) | |
44 easingFunction: cubicBezier(0.25, 0.1, 0.25, 1.0) | |
45 }, | |
46 { | |
47 desc: 'ease-in function', | |
48 easing: 'ease-in', // cubic-bezier(0.42, 0, 1.0, 1.0) | |
49 easingFunction: cubicBezier(0.42, 0, 1.0, 1.0) | |
50 }, | |
51 { | |
52 desc: 'ease-in-out function', | |
53 easing: 'ease-in-out', // cubic-bezier(0.42, 0, 0.58, 1.0) | |
54 easingFunction: cubicBezier(0.42, 0, 0.58, 1.0) | |
55 }, | |
56 { | |
57 desc: 'ease-out function', | |
58 easing: 'ease-out', // cubic-bezier(0, 0, 0.58, 1.0) | |
59 easingFunction: cubicBezier(0, 0, 0.58, 1.0) | |
60 }, | |
61 { | |
62 desc: 'easing function which produces values greater than 1', | |
63 easing: 'cubic-bezier(0, 1.5, 1, 1.5)', | |
64 easingFunction: cubicBezier(0, 1.5, 1, 1.5) | |
65 }, | |
66 { | |
67 desc: 'easing function which produces negative values', | |
68 easing: 'cubic-bezier(0, -0.5 ,1, -0.5)', | |
69 easingFunction: cubicBezier(0, -0.5, 1, -0.5) | |
70 }, | |
71 ]; | |
72 | |
73 gEffectEasingTests.forEach(function(options) { | |
74 test(function(t) { | |
75 var target = createDiv(t); | |
76 target.style.position = 'absolute'; | |
77 var anim = target.animate([ { left: '0px' }, { left: '100px' } ], | |
78 { duration: 1000, | |
79 fill: 'forwards', | |
80 easing: options.easing }); | |
81 var easing = options.easingFunction; | |
82 | |
83 anim.pause(); | |
84 | |
85 assert_style_left_at(anim, 0, easing); | |
86 assert_style_left_at(anim, 250, easing); | |
87 assert_style_left_at(anim, 500, easing); | |
88 assert_style_left_at(anim, 750, easing); | |
89 assert_style_left_at(anim, 1000, easing); | |
90 }, options.desc); | |
91 }); | |
92 | |
93 var gEffectEasingTestsWithKeyframeEasing = [ | |
94 { | |
95 desc: 'effect easing produces values greater than 1 with keyframe ' + | |
96 'easing cubic-bezier(0, 0, 0, 0)', | |
97 easing: 'cubic-bezier(0, 1.5, 1, 1.5)', | |
98 keyframeEasing: 'cubic-bezier(0, 0, 0, 0)', // linear | |
99 easingFunction: cubicBezier(0, 1.5, 1, 1.5) | |
100 }, | |
101 { | |
102 desc: 'effect easing produces values greater than 1 with keyframe ' + | |
103 'easing cubic-bezier(1, 1, 1, 1)', | |
104 easing: 'cubic-bezier(0, 1.5, 1, 1.5)', | |
105 keyframeEasing: 'cubic-bezier(1, 1, 1, 1)', // linear | |
106 easingFunction: cubicBezier(0, 1.5, 1, 1.5) | |
107 }, | |
108 { | |
109 desc: 'effect easing produces negative values 1 with keyframe ' + | |
110 'easing cubic-bezier(0, 0, 0, 0)', | |
111 easing: 'cubic-bezier(0, -0.5, 1, -0.5)', | |
112 keyframeEasing: 'cubic-bezier(0, 0, 0, 0)', // linear | |
113 easingFunction: cubicBezier(0, -0.5, 1, -0.5) | |
114 }, | |
115 { | |
116 desc: 'effect easing produces negative values 1 with keyframe ' + | |
117 'easing cubic-bezier(1, 1, 1, 1)', | |
118 easing: 'cubic-bezier(0, -0.5, 1, -0.5)', | |
119 keyframeEasing: 'cubic-bezier(1, 1, 1, 1)', // linear | |
120 easingFunction: cubicBezier(0, -0.5, 1, -0.5) | |
121 }, | |
122 ]; | |
123 | |
124 gEffectEasingTestsWithKeyframeEasing.forEach(function(options) { | |
125 test(function(t) { | |
126 var target = createDiv(t); | |
127 target.style.position = 'absolute'; | |
128 var anim = target.animate( | |
129 [ { left: '0px', easing: options.keyframeEasing }, | |
130 { left: '100px' } ], | |
131 { duration: 1000, | |
132 fill: 'forwards', | |
133 easing: options.easing }); | |
134 var easing = options.easingFunction; | |
135 | |
136 anim.pause(); | |
137 | |
138 assert_style_left_at(anim, 0, easing); | |
139 assert_style_left_at(anim, 250, easing); | |
140 assert_style_left_at(anim, 500, easing); | |
141 assert_style_left_at(anim, 750, easing); | |
142 assert_style_left_at(anim, 1000, easing); | |
143 }, options.desc); | |
144 }); | |
145 | |
146 // Other test cases that effect easing produces values outside of [0,1]. | |
147 test(function(t) { | |
148 var target = createDiv(t); | |
149 target.style.position = 'absolute'; | |
150 var anim = target.animate([ { left: '0px', easing: 'step-start' }, | |
151 { left: '100px' } ], | |
152 { duration: 1000, | |
153 fill: 'forwards', | |
154 easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }); | |
155 anim.pause(); | |
156 | |
157 // The bezier function produces values greater than 1 in (0.23368794, 1) | |
158 anim.currentTime = 0; | |
159 assert_equals(getComputedStyle(target).left, '100px'); | |
160 anim.currentTime = 230; | |
161 assert_equals(getComputedStyle(target).left, '100px'); | |
162 anim.currentTime = 250; | |
163 assert_equals(getComputedStyle(target).left, '100px'); | |
164 anim.currentTime = 1000; | |
165 assert_equals(getComputedStyle(target).left, '100px'); | |
166 }, 'effect easing produces values greater than 1 with step-start keyframe'); | |
167 | |
168 test(function(t) { | |
169 var target = createDiv(t); | |
170 target.style.position = 'absolute'; | |
171 var anim = target.animate([ { left: '0px', easing: 'step-end' }, | |
172 { left: '100px' } ], | |
173 { duration: 1000, | |
174 fill: 'forwards', | |
175 easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }); | |
176 anim.pause(); | |
177 | |
178 // The bezier function produces values greater than 1 in (0.23368794, 1) | |
179 anim.currentTime = 0; | |
180 assert_equals(getComputedStyle(target).left, '0px'); | |
181 anim.currentTime = 230; | |
182 assert_equals(getComputedStyle(target).left, '0px'); | |
183 anim.currentTime = 250; | |
184 assert_equals(getComputedStyle(target).left, '100px'); | |
185 anim.currentTime = 1000; | |
186 assert_equals(getComputedStyle(target).left, '100px'); | |
187 }, 'effect easing produces values greater than 1 with step-end keyframe'); | |
188 | |
189 test(function(t) { | |
190 var target = createDiv(t); | |
191 target.style.position = 'absolute'; | |
192 var anim = target.animate([ { left: '0px', easing: 'step-start' }, | |
193 { left: '100px' } ], | |
194 { duration: 1000, | |
195 fill: 'forwards', | |
196 easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }); | |
197 anim.pause(); | |
198 | |
199 // The bezier function produces negative values in (0, 0.766312060) | |
200 anim.currentTime = 0; | |
201 assert_equals(getComputedStyle(target).left, '100px'); | |
202 anim.currentTime = 750; | |
203 assert_equals(getComputedStyle(target).left, '0px'); | |
204 anim.currentTime = 800; | |
205 assert_equals(getComputedStyle(target).left, '100px'); | |
206 anim.currentTime = 1000; | |
207 assert_equals(getComputedStyle(target).left, '100px'); | |
208 }, 'effect easing produces negative values with step-start keyframe'); | |
209 | |
210 test(function(t) { | |
211 var target = createDiv(t); | |
212 target.style.position = 'absolute'; | |
213 var anim = target.animate([ { left: '0px', easing: 'step-end' }, | |
214 { left: '100px' } ], | |
215 { duration: 1000, | |
216 fill: 'forwards', | |
217 easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }); | |
218 anim.pause(); | |
219 | |
220 // The bezier function produces negative values in (0, 0.766312060) | |
221 anim.currentTime = 0; | |
222 assert_equals(getComputedStyle(target).left, '0px'); | |
223 anim.currentTime = 750; | |
224 assert_equals(getComputedStyle(target).left, '0px'); | |
225 anim.currentTime = 800; | |
226 assert_equals(getComputedStyle(target).left, '0px'); | |
227 anim.currentTime = 1000; | |
228 assert_equals(getComputedStyle(target).left, '100px'); | |
229 }, 'effect easing produces negative values with step-end keyframe'); | |
230 | |
231 test(function(t) { | |
232 var target = createDiv(t); | |
233 target.style.position = 'absolute'; | |
234 var anim = target.animate( | |
235 // http://cubic-bezier.com/#.5,1,.5,0 | |
236 [ { left: '0px', easing: 'cubic-bezier(0.5, 1, 0.5, 0)' }, | |
237 { left: '100px' } ], | |
238 { duration: 1000, | |
239 fill: 'forwards', | |
240 easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }); | |
241 var keyframeEasing = function(x) { | |
242 assert_greater_than_equal(x, 0.0, | |
243 'This function should be called in [0, 1.0] range'); | |
244 assert_less_than_equal(x, 1.0, | |
245 'This function should be called in [0, 1.0] range'); | |
246 return cubicBezier(0.5, 1, 0.5, 0)(x); | |
247 } | |
248 var keyframeEasingExtrapolated = function(x) { | |
249 assert_greater_than(x, 1.0, | |
250 'This function should be called in (1.0, infinity) range'); | |
251 // p3x + (p2y - p3y) / (p2x - p3x) * (x - p3x) | |
252 return 1.0 + (0 - 1) / (0.5 - 1) * (x - 1.0); | |
253 } | |
254 var effectEasing = function(x) { | |
255 return cubicBezier(0, 1.5, 1, 1.5)(x); | |
256 } | |
257 | |
258 anim.pause(); | |
259 | |
260 // The effect-easing produces values greater than 1 in (0.23368794, 1) | |
261 assert_style_left_at(anim, 0, function(x) { | |
262 return keyframeEasing(effectEasing(x)); | |
263 }); | |
264 assert_style_left_at(anim, 230, function(x) { | |
265 return keyframeEasing(effectEasing(x)); | |
266 }); | |
267 assert_style_left_at(anim, 240, function(x) { | |
268 return keyframeEasingExtrapolated(effectEasing(x)); | |
269 }); | |
270 // Near the extreme point of the effect-easing function | |
271 assert_style_left_at(anim, 700, function(x) { | |
272 return keyframeEasingExtrapolated(effectEasing(x)); | |
273 }); | |
274 assert_style_left_at(anim, 990, function(x) { | |
275 return keyframeEasingExtrapolated(effectEasing(x)); | |
276 }); | |
277 assert_style_left_at(anim, 1000, function(x) { | |
278 return keyframeEasing(effectEasing(x)); | |
279 }); | |
280 }, 'effect easing produces values greater than 1 with keyframe easing ' + | |
281 'producing values greater than 1'); | |
282 | |
283 test(function(t) { | |
284 var target = createDiv(t); | |
285 target.style.position = 'absolute'; | |
286 var anim = target.animate( | |
287 // http://cubic-bezier.com/#0,1.5,1,1.5 | |
288 [ { left: '0px', easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }, | |
289 { left: '100px' } ], | |
290 { duration: 1000, | |
291 fill: 'forwards', | |
292 easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }); | |
293 var easing = function(x) { | |
294 assert_greater_than_equal(x, 0.0, | |
295 'This function should be called in [0, 1.0] range'); | |
296 assert_less_than_equal(x, 1.0, | |
297 'This function should be called in [0, 1.0] range'); | |
298 return cubicBezier(0, 1.5, 1, 1.5)(x); | |
299 } | |
300 var easingExtrapolated = function(x) { | |
301 assert_greater_than(x, 1.0, | |
302 'This function should be called in negative range'); | |
303 // For cubic-bezier(0, 1.5, 1, 1.5), the tangent at the | |
304 // endpoint (x = 1.0) is infinity so we should just return 1.0. | |
305 return 1.0; | |
306 } | |
307 | |
308 anim.pause(); | |
309 | |
310 // The effect-easing produces values greater than 1 in (0.23368794, 1) | |
311 assert_style_left_at(anim, 0, function(x) { | |
312 return easing(easing(x)) | |
313 }); | |
314 assert_style_left_at(anim, 230, function(x) { | |
315 return easing(easing(x)) | |
316 }); | |
317 assert_style_left_at(anim, 240, function(x) { | |
318 return easingExtrapolated(easing(x)); | |
319 }); | |
320 // Near the extreme point of the effect-easing function | |
321 assert_style_left_at(anim, 700, function(x) { | |
322 return easingExtrapolated(easing(x)); | |
323 }); | |
324 assert_style_left_at(anim, 990, function(x) { | |
325 return easingExtrapolated(easing(x)); | |
326 }); | |
327 assert_style_left_at(anim, 1000, function(x) { | |
328 return easing(easing(x)) | |
329 }); | |
330 }, 'effect easing which produces values greater than 1 and the tangent on ' + | |
331 'the upper boundary is infinity with keyframe easing producing values ' + | |
332 'greater than 1'); | |
333 | |
334 test(function(t) { | |
335 var target = createDiv(t); | |
336 target.style.position = 'absolute'; | |
337 var anim = target.animate( | |
338 // http://cubic-bezier.com/#.5,1,.5,0 | |
339 [ { left: '0px', easing: 'cubic-bezier(0.5, 1, 0.5, 0)' }, | |
340 { left: '100px' } ], | |
341 { duration: 1000, | |
342 fill: 'forwards', | |
343 easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }); | |
344 var keyframeEasing = function(x) { | |
345 assert_greater_than_equal(x, 0.0, | |
346 'This function should be called in [0, 1.0] range'); | |
347 assert_less_than_equal(x, 1.0, | |
348 'This function should be called in [0, 1.0] range'); | |
349 return cubicBezier(0.5, 1, 0.5, 0)(x); | |
350 } | |
351 var keyframeEasingExtrapolated = function(x) { | |
352 assert_less_than(x, 0.0, | |
353 'This function should be called in negative range'); | |
354 // p0x + (p1y - p0y) / (p1x - p0x) * (x - p0x) | |
355 return (1 / 0.5) * x; | |
356 } | |
357 var effectEasing = function(x) { | |
358 return cubicBezier(0, -0.5, 1, -0.5)(x); | |
359 } | |
360 | |
361 anim.pause(); | |
362 | |
363 // The effect-easing produces negative values in (0, 0.766312060) | |
364 assert_style_left_at(anim, 0, function(x) { | |
365 return keyframeEasing(effectEasing(x)); | |
366 }); | |
367 assert_style_left_at(anim, 10, function(x) { | |
368 return keyframeEasingExtrapolated(effectEasing(x)); | |
369 }); | |
370 // Near the extreme point of the effect-easing function | |
371 assert_style_left_at(anim, 300, function(x) { | |
372 return keyframeEasingExtrapolated(effectEasing(x)); | |
373 }); | |
374 assert_style_left_at(anim, 750, function(x) { | |
375 return keyframeEasingExtrapolated(effectEasing(x)); | |
376 }); | |
377 assert_style_left_at(anim, 770, function(x) { | |
378 return keyframeEasing(effectEasing(x)); | |
379 }); | |
380 assert_style_left_at(anim, 1000, function(x) { | |
381 return keyframeEasing(effectEasing(x)); | |
382 }); | |
383 }, 'effect easing produces negative values with keyframe easing ' + | |
384 'producing negative values'); | |
385 | |
386 test(function(t) { | |
387 var target = createDiv(t); | |
388 target.style.position = 'absolute'; | |
389 var anim = target.animate( | |
390 // http://cubic-bezier.com/#0,-0.5,1,-0.5 | |
391 [ { left: '0px', easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }, | |
392 { left: '100px' } ], | |
393 { duration: 1000, | |
394 fill: 'forwards', | |
395 easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }); | |
396 var easing = function(x) { | |
397 assert_greater_than_equal(x, 0.0, | |
398 'This function should be called in [0, 1.0] range'); | |
399 assert_less_than_equal(x, 1.0, | |
400 'This function should be called in [0, 1.0] range'); | |
401 return cubicBezier(0, -0.5, 1, -0.5)(x); | |
402 } | |
403 var easingExtrapolated = function(x) { | |
404 assert_less_than(x, 0.0, | |
405 'This function should be called in negative range'); | |
406 // For cubic-bezier(0, -0.5, 1, -0.5), the tangent at the | |
407 // endpoint (x = 0.0) is infinity so we should just return 0.0. | |
408 return 0.0; | |
409 } | |
410 | |
411 anim.pause(); | |
412 | |
413 // The effect-easing produces negative values in (0, 0.766312060) | |
414 assert_style_left_at(anim, 0, function(x) { | |
415 return easing(easing(x)) | |
416 }); | |
417 assert_style_left_at(anim, 10, function(x) { | |
418 return easingExtrapolated(easing(x)); | |
419 }); | |
420 // Near the extreme point of the effect-easing function | |
421 assert_style_left_at(anim, 300, function(x) { | |
422 return easingExtrapolated(easing(x)); | |
423 }); | |
424 assert_style_left_at(anim, 750, function(x) { | |
425 return easingExtrapolated(easing(x)); | |
426 }); | |
427 assert_style_left_at(anim, 770, function(x) { | |
428 return easing(easing(x)) | |
429 }); | |
430 assert_style_left_at(anim, 1000, function(x) { | |
431 return easing(easing(x)) | |
432 }); | |
433 }, 'effect easing which produces negative values and the tangent on ' + | |
434 'the lower boundary is infinity with keyframe easing producing ' + | |
435 'negative values'); | |
436 | |
437 </script> | |
438 </body> | |
OLD | NEW |