cubic-bezier-timing-functions-output.html (7961B)
1 <!DOCTYPE html> 2 <meta charset=utf-8> 3 <meta name="assert" 4 content="This test checks the output of Cubic Bézier functions" /> 5 <title>Tests for the output of Cubic Bézier timing functions</title> 6 <link rel="help" 7 href="https://drafts.csswg.org/css-easing/#cubic-bezier-timing-functions"> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="testcommon.js"></script> 11 <body> 12 <div id="log"></div> 13 <script> 14 'use strict'; 15 16 // Precision of major rendering engines' layout systems. 17 const epsilon = 0.02; 18 19 function assert_style_left_at(animation, time, easingFunction) { 20 animation.currentTime = time; 21 var portion = time / animation.effect.getTiming()['duration']; 22 assert_approx_equals(pxToNum(getComputedStyle(animation.effect.target).left), 23 easingFunction(portion) * 100, 24 epsilon, 25 'The left of the animation should be approximately ' + 26 easingFunction(portion) * 100 + ' at ' + time + 'ms'); 27 } 28 29 test(function(t) { 30 var target = createDiv(t); 31 target.style.position = 'absolute'; 32 var anim = target.animate( 33 // http://cubic-bezier.com/#.5,1,.5,0 34 [ { left: '0px', easing: 'cubic-bezier(0.5, 1, 0.5, 0)' }, 35 { left: '100px' } ], 36 { duration: 1000, 37 fill: 'forwards', 38 easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }); 39 var keyframeEasing = function(x) { 40 assert_greater_than_equal(x, 0.0, 41 'This function should be called in [0, 1.0] range'); 42 assert_less_than_equal(x, 1.0, 43 'This function should be called in [0, 1.0] range'); 44 return cubicBezier(0.5, 1, 0.5, 0)(x); 45 } 46 var keyframeEasingExtrapolated = function(x) { 47 assert_greater_than(x, 1.0, 48 'This function should be called in (1.0, infinity) range'); 49 // p3x + (p2y - p3y) / (p2x - p3x) * (x - p3x) 50 return 1.0 + (0 - 1) / (0.5 - 1) * (x - 1.0); 51 } 52 var effectEasing = function(x) { 53 return cubicBezier(0, 1.5, 1, 1.5)(x); 54 } 55 56 // The effect-easing produces values greater than 1 in (0.23368794, 1) 57 assert_style_left_at(anim, 0, function(x) { 58 return keyframeEasing(effectEasing(x)); 59 }); 60 assert_style_left_at(anim, 230, function(x) { 61 return keyframeEasing(effectEasing(x)); 62 }); 63 assert_style_left_at(anim, 240, function(x) { 64 return keyframeEasingExtrapolated(effectEasing(x)); 65 }); 66 // Near the extreme point of the effect-easing function 67 assert_style_left_at(anim, 700, function(x) { 68 return keyframeEasingExtrapolated(effectEasing(x)); 69 }); 70 assert_style_left_at(anim, 990, function(x) { 71 return keyframeEasingExtrapolated(effectEasing(x)); 72 }); 73 assert_style_left_at(anim, 1000, function(x) { 74 return keyframeEasing(effectEasing(x)); 75 }); 76 }, 'cubic-bezier easing with input progress greater than 1'); 77 78 test(function(t) { 79 var target = createDiv(t); 80 target.style.position = 'absolute'; 81 var anim = target.animate( 82 // http://cubic-bezier.com/#0,1.5,1,1.5 83 [ { left: '0px', easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }, 84 { left: '100px' } ], 85 { duration: 1000, 86 fill: 'forwards', 87 easing: 'cubic-bezier(0, 1.5, 1, 1.5)' }); 88 var easing = function(x) { 89 assert_greater_than_equal(x, 0.0, 90 'This function should be called in [0, 1.0] range'); 91 assert_less_than_equal(x, 1.0, 92 'This function should be called in [0, 1.0] range'); 93 return cubicBezier(0, 1.5, 1, 1.5)(x); 94 } 95 var easingExtrapolated = function(x) { 96 assert_greater_than(x, 1.0, 97 'This function should be called in negative range'); 98 // For cubic-bezier(0, 1.5, 1, 1.5), the tangent at the 99 // endpoint (x = 1.0) is infinity so we should just return 1.0. 100 return 1.0; 101 } 102 103 // The effect-easing produces values greater than 1 in (0.23368794, 1) 104 assert_style_left_at(anim, 0, function(x) { 105 return easing(easing(x)) 106 }); 107 assert_style_left_at(anim, 230, function(x) { 108 return easing(easing(x)) 109 }); 110 assert_style_left_at(anim, 240, function(x) { 111 return easingExtrapolated(easing(x)); 112 }); 113 // Near the extreme point of the effect-easing function 114 assert_style_left_at(anim, 700, function(x) { 115 return easingExtrapolated(easing(x)); 116 }); 117 assert_style_left_at(anim, 990, function(x) { 118 return easingExtrapolated(easing(x)); 119 }); 120 assert_style_left_at(anim, 1000, function(x) { 121 return easing(easing(x)) 122 }); 123 }, 'cubic-bezier easing with input progress greater than 1 and where the ' + 124 'tangent on the upper boundary is infinity'); 125 126 test(function(t) { 127 var target = createDiv(t); 128 target.style.position = 'absolute'; 129 var anim = target.animate( 130 // http://cubic-bezier.com/#.5,1,.5,0 131 [ { left: '0px', easing: 'cubic-bezier(0.5, 1, 0.5, 0)' }, 132 { left: '100px' } ], 133 { duration: 1000, 134 fill: 'forwards', 135 easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }); 136 var keyframeEasing = function(x) { 137 assert_greater_than_equal(x, 0.0, 138 'This function should be called in [0, 1.0] range'); 139 assert_less_than_equal(x, 1.0, 140 'This function should be called in [0, 1.0] range'); 141 return cubicBezier(0.5, 1, 0.5, 0)(x); 142 } 143 var keyframeEasingExtrapolated = function(x) { 144 assert_less_than(x, 0.0, 145 'This function should be called in negative range'); 146 // p0x + (p1y - p0y) / (p1x - p0x) * (x - p0x) 147 return (1 / 0.5) * x; 148 } 149 var effectEasing = function(x) { 150 return cubicBezier(0, -0.5, 1, -0.5)(x); 151 } 152 153 // The effect-easing produces negative values in (0, 0.766312060) 154 assert_style_left_at(anim, 0, function(x) { 155 return keyframeEasing(effectEasing(x)); 156 }); 157 assert_style_left_at(anim, 10, function(x) { 158 return keyframeEasingExtrapolated(effectEasing(x)); 159 }); 160 // Near the extreme point of the effect-easing function 161 assert_style_left_at(anim, 300, function(x) { 162 return keyframeEasingExtrapolated(effectEasing(x)); 163 }); 164 assert_style_left_at(anim, 750, function(x) { 165 return keyframeEasingExtrapolated(effectEasing(x)); 166 }); 167 assert_style_left_at(anim, 770, function(x) { 168 return keyframeEasing(effectEasing(x)); 169 }); 170 assert_style_left_at(anim, 1000, function(x) { 171 return keyframeEasing(effectEasing(x)); 172 }); 173 }, 'cubic-bezier easing with input progress less than 0'); 174 175 test(function(t) { 176 var target = createDiv(t); 177 target.style.position = 'absolute'; 178 var anim = target.animate( 179 // http://cubic-bezier.com/#0,-0.5,1,-0.5 180 [ { left: '0px', easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }, 181 { left: '100px' } ], 182 { duration: 1000, 183 fill: 'forwards', 184 easing: 'cubic-bezier(0, -0.5, 1, -0.5)' }); 185 var easing = function(x) { 186 assert_greater_than_equal(x, 0.0, 187 'This function should be called in [0, 1.0] range'); 188 assert_less_than_equal(x, 1.0, 189 'This function should be called in [0, 1.0] range'); 190 return cubicBezier(0, -0.5, 1, -0.5)(x); 191 } 192 var easingExtrapolated = function(x) { 193 assert_less_than(x, 0.0, 194 'This function should be called in negative range'); 195 // For cubic-bezier(0, -0.5, 1, -0.5), the tangent at the 196 // endpoint (x = 0.0) is infinity so we should just return 0.0. 197 return 0.0; 198 } 199 200 // The effect-easing produces negative values in (0, 0.766312060) 201 assert_style_left_at(anim, 0, function(x) { 202 return easing(easing(x)) 203 }); 204 assert_style_left_at(anim, 10, function(x) { 205 return easingExtrapolated(easing(x)); 206 }); 207 // Near the extreme point of the effect-easing function 208 assert_style_left_at(anim, 300, function(x) { 209 return easingExtrapolated(easing(x)); 210 }); 211 assert_style_left_at(anim, 750, function(x) { 212 return easingExtrapolated(easing(x)); 213 }); 214 assert_style_left_at(anim, 770, function(x) { 215 return easing(easing(x)) 216 }); 217 assert_style_left_at(anim, 1000, function(x) { 218 return easing(easing(x)) 219 }); 220 }, 'cubic-bezier easing with input progress less than 0 and where the ' + 221 'tangent on the lower boundary is infinity'); 222 223 </script> 224 </body>