animate动画方法封装:原生JS实现
1 /** 2 * Created by guoyongfeng on 2014/7/7. 3 * @Author guoyongfeng 4 * @Date 2014-07-07 5 * @Version 1.0.0 6 * @update 2014-07-07 7 * @described tween动画库函数封装 8 * 9 */ 10 define('animate/0.0.1', function(){ 11 /** 12 * 13 */ 14 return function(ele, json, duration, effect, fnCallBack){ 15 //对传参effect进行判断,并将获得的方法统一赋值给action方法 16 //对传参的判断可以实现js的重载功能。 17 var action=null; 18 if(typeof effect =="number"){ 19 //1 buffer,2 flex,3 bounce 4 linear 20 switch(effect){ 21 case 1: 22 action=moveEffect.Exponential.easeOut; 23 break; 24 case 2: 25 action=moveEffect.Elastic.easeOut; 26 break; 27 case 3: 28 action=moveEffect.Bounce.easeOut; 29 break; 30 case 4: 31 action=moveEffect.Linear; 32 break; 33 default: 34 break; 35 } 36 }else if(typeof effect == 'string'){ 37 switch(effect){ 38 case 'Exponential': 39 action=moveEffect.Exponential.easeOut; 40 break; 41 case 'Elastic': 42 action=moveEffect.Elastic.easeOut; 43 break; 44 case 'Bounce': 45 action=moveEffect.Bounce.easeOut; 46 break; 47 case 'Linear': 48 action=moveEffect.Linear; 49 break; 50 default: 51 break; 52 } 53 54 }else if(typeof effect == "function"){ 55 //参数effect是个函数,则默认为这是回调函数,并采用默认的运动效果 56 fnCallback=effect; 57 }else if(effect instanceof Array){ 58 //输入格式:['Expo','easeOut'] 59 if(effect.length===2){ 60 action=moveEffect[effect[0]][effect[1]]; 61 }else if(effect.length==1){ 62 action=moveEffect.Linear; 63 } 64 }else{ 65 action=moveEffect.Exponential.easeOut; 66 } 67 68 //获取初试值 69 var oBegin={}; 70 var oChange={}; 71 for(var attr in json){ 72 var begin=0, change=0, count=0; 73 if(attr == 'opacity'){ 74 begin=Math.random((parseFloat(getStyle(ele, attr)))*100); 75 change=json[attr]-begin; 76 if(begin == 'undefined'){ 77 ele.style[attr]='alpha(opacity:100)'; 78 ele.style.opacity=1; 79 } 80 }else{ 81 begin=parseInt(getStyle(ele, attr)); 82 change=json[attr]-begin; 83 } 84 //保存 85 if(change){ 86 count++; 87 oBegin[attr]=begin; 88 oChange[attr]=change; 89 } 90 } 91 //判断所有变量是否到齐 92 if(count == 0){ 93 if(typeof fnCallBack == 'function'){ 94 fnCallBack.call(ele); 95 }else{ 96 return ; 97 } 98 } 99 100 //封装运动函数 101 var times=0; 102 var interval=30; 103 move(); 104 105 function move(){ 106 clearInterval(ele.timer); 107 times+=interval; 108 109 if(times<=duration){ 110 for(var attr in json){ 111 //var val=times*oChange[attr]/duration+oBegin[attr]; 112 var val=action(times, oBegin[attr], oChange[attr], duration); 113 if(attr == 'opacity'){ 114 ele.style[attr]=val/100; 115 ele.style.filter="alpha(opacity="+val+")"; 116 }else{ 117 ele.style[attr]=val+'px'; 118 } 119 } 120 ele.timer=window.setInterval(move, interval); 121 }else{ 122 if(attr == 'opacity'){ 123 ele.style[attr]=json[attr]/100; 124 ele.style.filter="alpha(opacity="+json[attr]+")"; 125 }else{ 126 ele.style[attr]=json[attr]+'px'; 127 } 128 //回调函数 129 if(typeof fnCallBack == 'function'){ 130 fnCallBack.call(ele); 131 } 132 133 ele.timer=null; 134 } 135 } 136 137 //获取css样式的兼容性写法 138 function getStyle(obj, attr){ 139 if(obj.currentStyle){ 140 return obj.currentStyle[attr]; 141 }else{ 142 return getComputedStyle(obj, null)[attr]; 143 } 144 } 145 146 } 147 148 //思路:当前时间*变化量/持续时间+初始值 149 var moveEffect = { 150 //1.线性运动 151 Linear: function(t,b,c,d){ 152 return c*t/d + b; 153 }, 154 //2.二次方的缓动(t^2); 155 Quadratic: { 156 easeIn: function(t,b,c,d){ 157 return c*(t/=d)*t + b; 158 }, 159 easeOut: function(t,b,c,d){ 160 return -c *(t/=d)*(t-2) + b; 161 }, 162 easeInOut: function(t,b,c,d){ 163 if ((t/=d/2) < 1) return c/2*t*t + b; 164 return -c/2 * ((--t)*(t-2) - 1) + b; 165 } 166 }, 167 //3.三次方的缓动(t^3) 168 Cubic: { 169 easeIn: function(t,b,c,d){ 170 return c*(t/=d)*t*t + b; 171 }, 172 easeOut: function(t,b,c,d){ 173 return c*((t=t/d-1)*t*t + 1) + b; 174 }, 175 easeInOut: function(t,b,c,d){ 176 if ((t/=d/2) < 1) return c/2*t*t*t + b; 177 return c/2*((t-=2)*t*t + 2) + b; 178 } 179 }, 180 //4.四次方的缓动(t^4); 181 Quartic: { 182 easeIn: function(t,b,c,d){ 183 return c*(t/=d)*t*t*t + b; 184 }, 185 easeOut: function(t,b,c,d){ 186 return -c * ((t=t/d-1)*t*t*t - 1) + b; 187 }, 188 easeInOut: function(t,b,c,d){ 189 if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 190 return -c/2 * ((t-=2)*t*t*t - 2) + b; 191 } 192 }, 193 //5.五次方的缓动(t^5); 194 Quintic: { 195 easeIn: function(t,b,c,d){ 196 return c*(t/=d)*t*t*t*t + b; 197 }, 198 easeOut: function(t,b,c,d){ 199 return c*((t=t/d-1)*t*t*t*t + 1) + b; 200 }, 201 easeInOut: function(t,b,c,d){ 202 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 203 return c/2*((t-=2)*t*t*t*t + 2) + b; 204 } 205 }, 206 //6.正弦曲线的缓动sin(t) 207 Sinusoidal: { 208 easeIn: function(t,b,c,d){ 209 return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 210 }, 211 easeOut: function(t,b,c,d){ 212 return c * Math.sin(t/d * (Math.PI/2)) + b; 213 }, 214 easeInOut: function(t,b,c,d){ 215 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 216 } 217 }, 218 //7.指数曲线的缓动(2^t); 219 Exponential: { 220 easeIn: function(t,b,c,d){ 221 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 222 }, 223 easeOut: function(t,b,c,d){ 224 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 225 }, 226 easeInOut: function(t,b,c,d){ 227 if (t==0) return b; 228 if (t==d) return b+c; 229 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 230 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 231 } 232 }, 233 //8.圆形曲线的缓动(sqrt(1-t^2)); 234 Circular: { 235 easeIn: function(t,b,c,d){ 236 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 237 }, 238 easeOut: function(t,b,c,d){ 239 return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 240 }, 241 easeInOut: function(t,b,c,d){ 242 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 243 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 244 } 245 }, 246 //9.指数衰减的正弦曲线缓动; 247 Elastic: { 248 easeIn: function(t,b,c,d,a,p){ 249 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 250 if (!a || a < Math.abs(c)) { a=c; var s=p/4; } 251 else var s = p/(2*Math.PI) * Math.asin (c/a); 252 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 253 }, 254 easeOut: function(t,b,c,d,a,p){ 255 if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 256 if (!a || a < Math.abs(c)) { a=c; var s=p/4; } 257 else var s = p/(2*Math.PI) * Math.asin (c/a); 258 return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b); 259 }, 260 easeInOut: function(t,b,c,d,a,p){ 261 if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 262 if (!a || a < Math.abs(c)) { a=c; var s=p/4; } 263 else var s = p/(2*Math.PI) * Math.asin (c/a); 264 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; 265 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; 266 } 267 }, 268 //10.超过范围的三次方缓动((s+1)*t^3 - s*t^2); 269 Back: { 270 easeIn: function(t,b,c,d,s){ 271 if (s == undefined) s = 1.70158; 272 return c*(t/=d)*t*((s+1)*t - s) + b; 273 }, 274 easeOut: function(t,b,c,d,s){ 275 if (s == undefined) s = 1.70158; 276 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 277 }, 278 easeInOut: function(t,b,c,d,s){ 279 if (s == undefined) s = 1.70158; 280 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 281 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 282 } 283 }, 284 //11.指数衰减的反弹缓动。 285 Bounce: { 286 easeIn: function(t,b,c,d){ 287 return c - moveEffect.Bounce.easeOut(d-t, 0, c, d) + b; 288 }, 289 easeOut: function(t,b,c,d){ 290 if ((t/=d) < (1/2.75)) { 291 return c*(7.5625*t*t) + b; 292 } else if (t < (2/2.75)) { 293 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 294 } else if (t < (2.5/2.75)) { 295 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 296 } else { 297 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 298 } 299 }, 300 easeInOut: function(t,b,c,d){ 301 if (t < d/2) return moveEffect.Bounce.easeIn(t*2, 0, c, d) * .5 + b; 302 else return moveEffect.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b; 303 } 304 } 305 }; 306 });