1 /**
  2  * Hilo
  3  * Copyright 2015 alibaba.com
  4  * Licensed under the MIT License
  5  */
  6 
  7 /**
  8  * @class Ease类包含为Tween类提供各种缓动功能的函数。
  9  * @module hilo/tween/Ease
 10  * @static
 11  */
 12 var Ease = (function(){
 13 
 14 function createEase(obj, easeInFn, easeOutFn, easeInOutFn, easeNoneFn){
 15     obj = obj || {};
 16     easeInFn && (obj.EaseIn = easeInFn);
 17     easeOutFn && (obj.EaseOut = easeOutFn);
 18     easeInOutFn && (obj.EaseInOut = easeInOutFn);
 19     easeNoneFn && (obj.EaseNone = easeNoneFn);
 20     return obj;
 21 }
 22 
 23 /**
 24  * 线性匀速缓动函数。包含EaseNone函数。
 25  */
 26 var Linear = createEase(null, null, null, null, function(k){
 27     return k;
 28 });
 29 
 30 /**
 31  * 二次缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
 32  */
 33 var Quad = createEase(null,
 34     function(k){
 35         return k * k;
 36     },
 37 
 38     function(k){
 39         return - k * (k - 2);
 40     },
 41 
 42     function(k){
 43         return ((k *= 2) < 1) ? 0.5 * k * k : -0.5 * (--k * (k - 2) - 1);
 44     }
 45 );
 46 
 47 /**
 48  * 三次缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
 49  */
 50 var Cubic = createEase(null,
 51     function(k){
 52         return k * k * k;
 53     },
 54 
 55     function(k){
 56         return --k * k * k + 1;
 57     },
 58 
 59     function(k){
 60         return ((k *= 2) < 1) ? 0.5 * k * k * k : 0.5 * ((k -= 2) * k * k + 2);
 61     }
 62 );
 63 
 64 /**
 65  * 四次缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
 66  */
 67 var Quart = createEase(null,
 68     function(k){
 69         return k * k * k * k;
 70     },
 71 
 72     function(k){
 73         return -(--k * k * k * k - 1);
 74     },
 75 
 76     function(k){
 77         return ((k *= 2) < 1) ? 0.5 * k * k * k * k : - 0.5 * ((k -= 2) * k * k * k - 2);
 78     }
 79 );
 80 
 81 /**
 82  * 五次缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
 83  */
 84 var Quint = createEase(null,
 85     function(k){
 86         return k * k * k * k * k;
 87     },
 88 
 89     function(k){
 90         return (k = k - 1) * k * k * k * k + 1;
 91     },
 92 
 93     function(k){
 94         return ((k *= 2) < 1) ? 0.5 * k * k * k * k * k : 0.5 * ((k -= 2) * k * k * k * k + 2);
 95     }
 96 );
 97 
 98 var math = Math,
 99     PI = math.PI, HALF_PI = PI * 0.5,
100     sin = math.sin, cos = math.cos,
101     pow = math.pow, sqrt = math.sqrt;
102 
103 /**
104  * 正弦缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
105  */
106 var Sine = createEase(null,
107     function(k){
108         return -cos(k * HALF_PI) + 1;
109     },
110 
111     function(k){
112         return sin(k * HALF_PI);
113     },
114 
115     function(k){
116         return -0.5 * (cos(PI * k) - 1);
117     }
118 );
119 
120 /**
121  * 指数缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
122  */
123 var Expo = createEase(null,
124     function(k){
125         return k == 0 ? 0 : pow(2, 10 * (k - 1));
126     },
127 
128     function(k){
129         return k == 1 ? 1 : -pow(2, -10 * k) + 1;
130     },
131 
132     function(k){
133         if(k == 0 || k == 1) return k;
134         if((k *= 2) < 1) return 0.5 * pow(2, 10 * (k - 1));
135         return 0.5 * (-pow(2, - 10 * (k - 1)) + 2);
136     }
137 );
138 
139 /**
140  * 圆形缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
141  */
142 var Circ = createEase(null,
143     function(k){
144         return -(sqrt(1 - k * k) - 1);
145     },
146 
147     function(k){
148         return sqrt(1 - (--k * k));
149     },
150 
151     function(k){
152         if((k /= 0.5) < 1) return - 0.5 * (sqrt(1 - k * k) - 1);
153         return 0.5 * (sqrt(1 - (k -= 2) * k) + 1);
154     }
155 );
156 
157 /**
158  * 弹性缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
159  */
160 var Elastic = createEase(
161     {
162         a: 1,
163         p: 0.4,
164         s: 0.1,
165 
166         config: function(amplitude, period){
167             Elastic.a = amplitude;
168             Elastic.p = period;
169             Elastic.s = period / (2 * PI) * Math.asin(1 / amplitude) || 0;
170         }
171     },
172 
173     function(k){
174         return -(Elastic.a * pow(2, 10 * (k -= 1)) * sin((k - Elastic.s) * (2 * PI) / Elastic.p));
175     },
176 
177     function(k){
178         return (Elastic.a * pow(2, -10 * k) * sin((k - Elastic.s) * (2 * PI) / Elastic.p) + 1);
179     },
180 
181     function(k){
182         return ((k *= 2) < 1) ? -0.5 * (Elastic.a * pow(2, 10 * (k -= 1)) * sin((k - Elastic.s) * (2 * PI) / Elastic.p)) :
183                Elastic.a * pow(2, -10 * (k -= 1)) * sin((k - Elastic.s) * (2 * PI) / Elastic.p) * 0.5 + 1;
184     }
185 );
186 
187 /**
188  * 向后缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
189  */
190 var Back = createEase(
191     {
192         o: 1.70158,
193         s: 2.59491,
194 
195         config: function(overshoot){
196             Back.o = overshoot;
197             Back.s = overshoot * 1.525;
198         }
199     },
200 
201     function(k){
202         return k * k * ((Back.o + 1) * k - Back.o);
203     },
204 
205     function(k){
206         return (k = k - 1) * k * ((Back.o + 1) * k + Back.o) + 1;
207     },
208 
209     function(k){
210         return ((k *= 2) < 1) ? 0.5 * (k * k * ((Back.s + 1) * k - Back.s)) : 0.5 * ((k -= 2) * k * ((Back.s + 1) * k + Back.s) + 2);
211     }
212 );
213 
214 /**
215  * 弹跳缓动函数。包含EaseIn、EaseOut、EaseInOut三个函数。
216  */
217 var Bounce = createEase(null,
218     function(k){
219         return 1 - Bounce.EaseOut(1 - k);
220     },
221 
222     function(k){
223         if((k /= 1) < 0.36364){
224             return 7.5625 * k * k;
225         }else if(k < 0.72727){
226             return 7.5625 * (k -= 0.54545) * k + 0.75;
227         }else if(k < 0.90909){
228             return 7.5625 * (k -= 0.81818) * k + 0.9375;
229         }else{
230             return 7.5625 * (k -= 0.95455) * k + 0.984375;
231         }
232     },
233 
234     function(k){
235         return k < 0.5 ? Bounce.EaseIn(k * 2) * 0.5 : Bounce.EaseOut(k * 2 - 1) * 0.5 + 0.5;
236     }
237 );
238 
239 return {
240     Linear: Linear,
241     Quad: Quad,
242     Cubic: Cubic,
243     Quart: Quart,
244     Quint: Quint,
245     Sine: Sine,
246     Expo: Expo,
247     Circ: Circ,
248     Elastic: Elastic,
249     Back: Back,
250     Bounce: Bounce
251 };
252 
253 })();