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