软件项目技术点(1)——Tween算法及缓动效果

AxeSlide软件项目梳理   canvas绘图系列知识点整理

Tween算法及缓动效果

软件里在切换步序时需要有过渡动画效果,从当前位置的画面缓动到目标位置的画面。动画效果可重新查看文章系列第一篇《AxeSlide软件项目梳理》中的作品展示动画。

实例效果:

 


Tween类型:

ease类型:

效果说明:
Linear:无缓动效果;
Quadratic:二次方的缓动(t^2);
Cubic:三次方的缓动(t^3);
Quartic:四次方的缓动(t^4);
Quintic:五次方的缓动(t^5);
Sinusoidal:正弦曲线的缓动(sin(t));
Exponential:指数曲线的缓动(2^t);
Circular:圆形曲线的缓动(sqrt(1-t^2));
Elastic:指数衰减的正弦曲线缓动;
Back:超过范围的三次方缓动((s+1)*t^3 - s*t^2);
Bounce:指数衰减的反弹缓动。
ps:以上都是自己的烂翻译,希望各位修正。

每个效果都分三个缓动方式(方法),分别是:
easeIn:从0开始加速的缓动;
easeOut:减速到0的缓动;
easeInOut:前半段从0开始加速,后半段减速到0的缓动。
其中Linear是无缓动效果,没有以上效果。

参数及使用示例:

Tween中的方法接受4个参数t,b,c,d 。返回值为计算后的当前位置。

四个参数分别是:
t: current time(当前时间);
b: beginning value(初始值);
c: change in value(变化量);
d: duration(持续时间)。

比如: 希望top从100px到150px,在500ms内完成

 1 var easeInQuad = function (x, t, b, c, d) {
 2     return c*(t/=d)*t + b;
 3 },
 4 
 5 var d = 500,b = 100,c = 150 - b;
 6 var count = d / 20; //500毫秒分多少次执行完毕
 7 setInterval(function(){
 8     var x = easeInQuad(0, d - (count-- * 20) , b, c, d);
 9     //return 的结果便是每个时间片,top的值
10 }, 20);
11 //一般浏览器的timer最小是20(这是windows底层的CPU时间决定的!)

 

Tween完整算法代码

  1     export class Tween{
  2         static Linear = function (t, b, c, d) { return c * t / d + b; };
  3         static Quad = {
  4             easeIn: function (t, b, c, d) {
  5                 return c * (t /= d) * t + b;
  6             },
  7             easeOut: function (t, b, c, d) {
  8                 return -c * (t /= d) * (t - 2) + b;
  9             },
 10             easeInOut: function (t, b, c, d) {
 11                 if ((t /= d / 2) < 1) return c / 2 * t * t + b;
 12                 return -c / 2 * ((--t) * (t - 2) - 1) + b;
 13             }
 14         };
 15         static Cubic = {
 16             easeIn: function (t, b, c, d) {
 17                 return c * (t /= d) * t * t + b;
 18             },
 19             easeOut: function (t, b, c, d) {
 20                 return c * ((t = t / d - 1) * t * t + 1) + b;
 21             },
 22             easeInOut: function (t, b, c, d) {
 23                 if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
 24                 return c / 2 * ((t -= 2) * t * t + 2) + b;
 25             }
 26         };
 27         static Quart = {
 28             easeIn: function (t, b, c, d) {
 29                 return c * (t /= d) * t * t * t + b;
 30             },
 31             easeOut: function (t, b, c, d) {
 32                 return -c * ((t = t / d - 1) * t * t * t - 1) + b;
 33             },
 34             easeInOut: function (t, b, c, d) {
 35                 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
 36                 return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
 37             }
 38         };
 39         static Quint = {
 40             easeIn: function (t, b, c, d) {
 41                 return c * (t /= d) * t * t * t * t + b;
 42             },
 43             easeOut: function (t, b, c, d) {
 44                 return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
 45             },
 46             easeInOut: function (t, b, c, d) {
 47                 if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
 48                 return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
 49             }
 50         };
 51         static Sine = {
 52             easeIn: function (t, b, c, d) {
 53                 return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
 54             },
 55             easeOut: function (t, b, c, d) {
 56                 return c * Math.sin(t / d * (Math.PI / 2)) + b;
 57             },
 58             easeInOut: function (t, b, c, d) {
 59                 return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
 60             }
 61         };
 62         static Expo = {
 63             easeIn: function (t, b, c, d) {
 64                 return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
 65             },
 66             easeOut: function (t, b, c, d) {
 67                 return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
 68             },
 69             easeInOut: function (t, b, c, d) {
 70                 if (t == 0) return b;
 71                 if (t == d) return b + c;
 72                 if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
 73                 return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
 74             }
 75         };
 76         static Circ = {
 77             easeIn: function (t, b, c, d) {
 78                 return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
 79             },
 80             easeOut: function (t, b, c, d) {
 81                 return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
 82             },
 83             easeInOut: function (t, b, c, d) {
 84                 if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
 85                 return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
 86             }
 87         };
 88         static Elastic = {
 89             easeIn: function (t, b, c, d, a, p) {
 90                 var s;
 91                 if (t == 0) return b;
 92                 if ((t /= d) == 1) return b + c;
 93                 if (typeof p == "undefined") p = d * .3;
 94                 if (!a || a < Math.abs(c)) {
 95                     s = p / 4;
 96                     a = c;
 97                 } else {
 98                     s = p / (2 * Math.PI) * Math.asin(c / a);
 99                 }
100                 return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
101             },
102             easeOut: function (t, b, c, d, a, p) {
103                 var s;
104                 if (t == 0) return b;
105                 if ((t /= d) == 1) return b + c;
106                 if (typeof p == "undefined") p = d * .3;
107                 if (!a || a < Math.abs(c)) {
108                     a = c;
109                     s = p / 4;
110                 } else {
111                     s = p / (2 * Math.PI) * Math.asin(c / a);
112                 }
113                 return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
114             },
115             easeInOut: function (t, b, c, d, a, p) {
116                 var s;
117                 if (t == 0) return b;
118                 if ((t /= d / 2) == 2) return b + c;
119                 if (typeof p == "undefined") p = d * (.3 * 1.5);
120                 if (!a || a < Math.abs(c)) {
121                     a = c;
122                     s = p / 4;
123                 } else {
124                     s = p / (2 * Math.PI) * Math.asin(c / a);
125                 }
126                 if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
127                 return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
128             }
129         };
130         static Back = {
131             easeIn: function (t, b, c, d, s) {
132                 if (typeof s == "undefined") s = 1.70158;
133                 return c * (t /= d) * t * ((s + 1) * t - s) + b;
134             },
135             easeOut: function (t, b, c, d, s) {
136                 if (typeof s == "undefined") s = 1.70158;
137                 return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
138             },
139             easeInOut: function (t, b, c, d, s) {
140                 if (typeof s == "undefined") s = 1.70158;
141                 if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
142                 return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
143             }
144         };
145         static Bounce = {
146             easeIn: function (t, b, c, d) {
147                 return c - Animation.Bounce.easeOut(d - t, 0, c, d) + b;
148             },
149             easeOut: function (t, b, c, d) {
150                 if ((t /= d) < (1 / 2.75)) {
151                     return c * (7.5625 * t * t) + b;
152                 } else if (t < (2 / 2.75)) {
153                     return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
154                 } else if (t < (2.5 / 2.75)) {
155                     return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
156                 } else {
157                     return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
158                 }
159             },
160             easeInOut: function (t, b, c, d) {
161                 if (t < d / 2) {
162                     return Animation.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
163                 } else {
164                     return Animation.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
165                 }
166             }
167         }
168     }

 

posted @ 2017-02-20 15:22  方帅  阅读(858)  评论(0编辑  收藏  举报