1 /** 2 * @fileOverview Easing equation from yui3 3 */ 4 KISSY.add('anim/easing', function () { 5 6 // Based on Easing Equations (c) 2003 Robert Penner, all rights reserved. 7 // This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html 8 // Preview: http://www.robertpenner.com/Easing/easing_demo.html 9 10 /** 11 * 和 YUI 的 Easing 相比,S.Easing 进行了归一化处理,参数调整为: 12 * @param {Number} t Time value used to compute current value 保留 0 =< t <= 1 13 * @param {Number} b Starting value b = 0 14 * @param {Number} c Delta between start and end values c = 1 15 * @param {Number} d Total length of animation d = 1 16 */ 17 18 var PI = Math.PI, 19 pow = Math.pow, 20 sin = Math.sin, 21 BACK_CONST = 1.70158; 22 /** 23 * @memberOf Anim 24 * @name Easing 25 * @namespace Provides methods for customizing how an animation behaves during each run. 26 */ 27 var Easing = 28 /** 29 * @lends Anim.Easing 30 */ 31 { 32 33 swing:function (t) { 34 return ( -Math.cos(t * PI) / 2 ) + 0.5; 35 }, 36 37 /** 38 * Uniform speed between points. 39 */ 40 easeNone:function (t) { 41 return t; 42 }, 43 44 /** 45 * Begins slowly and accelerates towards end. (quadratic) 46 */ 47 easeIn:function (t) { 48 return t * t; 49 }, 50 51 /** 52 * Begins quickly and decelerates towards end. (quadratic) 53 */ 54 easeOut:function (t) { 55 return ( 2 - t) * t; 56 }, 57 58 /** 59 * Begins slowly and decelerates towards end. (quadratic) 60 */ 61 easeBoth:function (t) { 62 return (t *= 2) < 1 ? 63 .5 * t * t : 64 .5 * (1 - (--t) * (t - 2)); 65 }, 66 67 /** 68 * Begins slowly and accelerates towards end. (quartic) 69 */ 70 easeInStrong:function (t) { 71 return t * t * t * t; 72 }, 73 74 /** 75 * Begins quickly and decelerates towards end. (quartic) 76 */ 77 easeOutStrong:function (t) { 78 return 1 - (--t) * t * t * t; 79 }, 80 81 /** 82 * Begins slowly and decelerates towards end. (quartic) 83 */ 84 easeBothStrong:function (t) { 85 return (t *= 2) < 1 ? 86 .5 * t * t * t * t : 87 .5 * (2 - (t -= 2) * t * t * t); 88 }, 89 90 /** 91 * Snap in elastic effect. 92 */ 93 94 elasticIn:function (t) { 95 var p = .3, s = p / 4; 96 if (t === 0 || t === 1) return t; 97 return -(pow(2, 10 * (t -= 1)) * sin((t - s) * (2 * PI) / p)); 98 }, 99 100 /** 101 * Snap out elastic effect. 102 */ 103 elasticOut:function (t) { 104 var p = .3, s = p / 4; 105 if (t === 0 || t === 1) return t; 106 return pow(2, -10 * t) * sin((t - s) * (2 * PI) / p) + 1; 107 }, 108 109 /** 110 * Snap both elastic effect. 111 */ 112 elasticBoth:function (t) { 113 var p = .45, s = p / 4; 114 if (t === 0 || (t *= 2) === 2) return t; 115 116 if (t < 1) { 117 return -.5 * (pow(2, 10 * (t -= 1)) * 118 sin((t - s) * (2 * PI) / p)); 119 } 120 return pow(2, -10 * (t -= 1)) * 121 sin((t - s) * (2 * PI) / p) * .5 + 1; 122 }, 123 124 /** 125 * Backtracks slightly, then reverses direction and moves to end. 126 */ 127 backIn:function (t) { 128 if (t === 1) t -= .001; 129 return t * t * ((BACK_CONST + 1) * t - BACK_CONST); 130 }, 131 132 /** 133 * Overshoots end, then reverses and comes back to end. 134 */ 135 backOut:function (t) { 136 return (t -= 1) * t * ((BACK_CONST + 1) * t + BACK_CONST) + 1; 137 }, 138 139 /** 140 * Backtracks slightly, then reverses direction, overshoots end, 141 * then reverses and comes back to end. 142 */ 143 backBoth:function (t) { 144 var s = BACK_CONST; 145 var m = (s *= 1.525) + 1; 146 147 if ((t *= 2 ) < 1) { 148 return .5 * (t * t * (m * t - s)); 149 } 150 return .5 * ((t -= 2) * t * (m * t + s) + 2); 151 152 }, 153 154 /** 155 * Bounce off of start. 156 */ 157 bounceIn:function (t) { 158 return 1 - Easing.bounceOut(1 - t); 159 }, 160 161 /** 162 * Bounces off end. 163 */ 164 bounceOut:function (t) { 165 var s = 7.5625, r; 166 167 if (t < (1 / 2.75)) { 168 r = s * t * t; 169 } 170 else if (t < (2 / 2.75)) { 171 r = s * (t -= (1.5 / 2.75)) * t + .75; 172 } 173 else if (t < (2.5 / 2.75)) { 174 r = s * (t -= (2.25 / 2.75)) * t + .9375; 175 } 176 else { 177 r = s * (t -= (2.625 / 2.75)) * t + .984375; 178 } 179 180 return r; 181 }, 182 183 /** 184 * Bounces off start and end. 185 */ 186 bounceBoth:function (t) { 187 if (t < .5) { 188 return Easing.bounceIn(t * 2) * .5; 189 } 190 return Easing.bounceOut(t * 2 - 1) * .5 + .5; 191 } 192 }; 193 194 return Easing; 195 }); 196 197 /** 198 * TODO: 199 * - test-Easing.html 详细的测试 + 曲线可视化 200 * 201 * NOTES: 202 * - 综合比较 jQuery UI/scripty2/YUI 的 Easing 命名,还是觉得 YUI 的对用户 203 * 最友好。因此这次完全照搬 YUI 的 Easing, 只是代码上做了点压缩优化。 204 * - 和原生对应关系: 205 * Easing.NativeTimeFunction = { 206 * easeNone: 'linear', 207 * ease: 'ease', 208 * 209 * easeIn: 'ease-in', 210 * easeOut: 'ease-out', 211 * easeBoth: 'ease-in-out', 212 * 213 * // Ref: 214 * // 1. http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag 215 * // 2. http://www.robertpenner.com/Easing/easing_demo.html 216 * // 3. assets/cubic-bezier-timing-function.html 217 * // 注:是模拟值,非精确推导值 218 * easeInStrong: 'cubic-bezier(0.9, 0.0, 0.9, 0.5)', 219 * easeOutStrong: 'cubic-bezier(0.1, 0.5, 0.1, 1.0)', 220 * easeBothStrong: 'cubic-bezier(0.9, 0.0, 0.1, 1.0)' 221 * }; 222 */ 223