公式一:
var Tween = {Linear: function(t, b, c, d) {return c * t / d + b;},Quad: {easeIn: function(t, b, c, d) {return c * (t /= d) * t + b;},easeOut: function(t, b, c, d) {return - c * (t /= d) * (t - 2) + b;},easeInOut: function(t, b, c, d) {if ((t /= d / 2) < 1) return c / 2 * t * t + b;return - c / 2 * ((--t) * (t - 2) - 1) + b;}},Cubic: {easeIn: function(t, b, c, d) {return c * (t /= d) * t * t + b;},easeOut: function(t, b, c, d) {return c * ((t = t / d - 1) * t * t + 1) + b;},easeInOut: function(t, b, c, d) {if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;return c / 2 * ((t -= 2) * t * t + 2) + b;}},Quart: {easeIn: function(t, b, c, d) {return c * (t /= d) * t * t * t + b;},easeOut: function(t, b, c, d) {return - c * ((t = t / d - 1) * t * t * t - 1) + b;},easeInOut: function(t, b, c, d) {if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;return - c / 2 * ((t -= 2) * t * t * t - 2) + b;}},Quint: {easeIn: function(t, b, c, d) {return c * (t /= d) * t * t * t * t + b;},easeOut: function(t, b, c, d) {return c * ((t = t / d - 1) * t * t * t * t + 1) + b;},easeInOut: function(t, b, c, d) {if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;}},Sine: {easeIn: function(t, b, c, d) {return - c * Math.cos(t / d * (Math.PI / 2)) + c + b;},easeOut: function(t, b, c, d) {return c * Math.sin(t / d * (Math.PI / 2)) + b;},easeInOut: function(t, b, c, d) {return - c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;}},Expo: {easeIn: function(t, b, c, d) {return (t == 0) ? b: c * Math.pow(2, 10 * (t / d - 1)) + b;},easeOut: function(t, b, c, d) {return (t == d) ? b + c: c * ( - Math.pow(2, -10 * t / d) + 1) + b;},easeInOut: function(t, b, c, d) {if (t == 0) return b;if (t == d) return b + c;if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;return c / 2 * ( - Math.pow(2, -10 * --t) + 2) + b;}},Circ: {easeIn: function(t, b, c, d) {return - c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;},easeOut: function(t, b, c, d) {return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;},easeInOut: function(t, b, c, d) {if ((t /= d / 2) < 1) return - c / 2 * (Math.sqrt(1 - t * t) - 1) + b;return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;}},Elastic: {easeIn: function(t, b, c, d, a, p) {if (t == 0) return b;if ((t /= d) == 1) return b + c;if (!p) p = d * .3;if (!a || a < Math.abs(c)) {a = c;var s = p / 4;} else var s = p / (2 * Math.PI) * Math.asin(c / a);return - (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;},easeOut: function(t, b, c, d, a, p) {if (t == 0) return b;if ((t /= d) == 1) return b + c;if (!p) p = d * .3;if (!a || a < Math.abs(c)) {a = c;var s = p / 4;} else var s = p / (2 * Math.PI) * Math.asin(c / a);return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);},easeInOut: function(t, b, c, d, a, p) {if (t == 0) return b;if ((t /= d / 2) == 2) return b + c;if (!p) p = d * (.3 * 1.5);if (!a || a < Math.abs(c)) {a = c;var s = p / 4;} else var s = p / (2 * Math.PI) * Math.asin(c / a);if (t < 1) return - .5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;}},Back: {easeIn: function(t, b, c, d, s) {if (s == undefined) s = 1.70158;return c * (t /= d) * t * ((s + 1) * t - s) + b;},easeOut: function(t, b, c, d, s) {if (s == undefined) s = 1.70158;return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;},easeInOut: function(t, b, c, d, s) {if (s == undefined) s = 1.70158;if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;}},Bounce: {easeIn: function(t, b, c, d) {return c - Tween.Bounce.easeOut(d - t, 0, c, d) + b;},easeOut: function(t, b, c, d) {if ((t /= d) < (1 / 2.75)) {return c * (7.5625 * t * t) + b;} else if (t < (2 / 2.75)) {return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;} else if (t < (2.5 / 2.75)) {return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;} else {return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;}},easeInOut: function(t, b, c, d) {if (t < d / 2) return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;else return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;}}}
公式二:
var tween = {easeInQuad: function(pos) {return Math.pow(pos, 2);},easeOutQuad: function(pos) {return - (Math.pow((pos - 1), 2) - 1);},easeInOutQuad: function(pos) {if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 2);return - 0.5 * ((pos -= 2) * pos - 2);},easeInCubic: function(pos) {return Math.pow(pos, 3);},easeOutCubic: function(pos) {return (Math.pow((pos - 1), 3) + 1);},easeInOutCubic: function(pos) {if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 3);return 0.5 * (Math.pow((pos - 2), 3) + 2);},easeInQuart: function(pos) {return Math.pow(pos, 4);},easeOutQuart: function(pos) {return - (Math.pow((pos - 1), 4) - 1)},easeInOutQuart: function(pos) {if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 4);return - 0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2);},easeInQuint: function(pos) {return Math.pow(pos, 5);},easeOutQuint: function(pos) {return (Math.pow((pos - 1), 5) + 1);},easeInOutQuint: function(pos) {if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 5);return 0.5 * (Math.pow((pos - 2), 5) + 2);},easeInSine: function(pos) {return - Math.cos(pos * (Math.PI / 2)) + 1;},easeOutSine: function(pos) {return Math.sin(pos * (Math.PI / 2));},easeInOutSine: function(pos) {return ( - .5 * (Math.cos(Math.PI * pos) - 1));},easeInExpo: function(pos) {return (pos == 0) ? 0 : Math.pow(2, 10 * (pos - 1));},easeOutExpo: function(pos) {return (pos == 1) ? 1 : -Math.pow(2, -10 * pos) + 1;},easeInOutExpo: function(pos) {if (pos == 0) return 0;if (pos == 1) return 1;if ((pos /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (pos - 1));return 0.5 * ( - Math.pow(2, -10 * --pos) + 2);},easeInCirc: function(pos) {return - (Math.sqrt(1 - (pos * pos)) - 1);},easeOutCirc: function(pos) {return Math.sqrt(1 - Math.pow((pos - 1), 2))},easeInOutCirc: function(pos) {if ((pos /= 0.5) < 1) return - 0.5 * (Math.sqrt(1 - pos * pos) - 1);return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1);},easeOutBounce: function(pos) {if ((pos) < (1 / 2.75)) {return (7.5625 * pos * pos);} else if (pos < (2 / 2.75)) {return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75);} else if (pos < (2.5 / 2.75)) {return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375);} else {return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375);}},easeInBack: function(pos) {var s = 1.70158;return (pos) * pos * ((s + 1) * pos - s);},easeOutBack: function(pos) {var s = 1.70158;return (pos = pos - 1) * pos * ((s + 1) * pos + s) + 1;},easeInOutBack: function(pos) {var s = 1.70158;if ((pos /= 0.5) < 1) return 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s));return 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);},elastic: function(pos) {return - 1 * Math.pow(4, -8 * pos) * Math.sin((pos * 6 - 1) * (2 * Math.PI) / 2) + 1;},swingFromTo: function(pos) {var s = 1.70158;return ((pos /= 0.5) < 1) ? 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) : 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);},swingFrom: function(pos) {var s = 1.70158;return pos * pos * ((s + 1) * pos - s);},swingTo: function(pos) {var s = 1.70158;return (pos -= 1) * pos * ((s + 1) * pos + s) + 1;},bounce: function(pos) {if (pos < (1 / 2.75)) {return (7.5625 * pos * pos);} else if (pos < (2 / 2.75)) {return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75);} else if (pos < (2.5 / 2.75)) {return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375);} else {return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375);}},bouncePast: function(pos) {if (pos < (1 / 2.75)) {return (7.5625 * pos * pos);} else if (pos < (2 / 2.75)) {return 2 - (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75);} else if (pos < (2.5 / 2.75)) {return 2 - (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375);} else {return 2 - (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375);}},easeFromTo: function(pos) {if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 4);return - 0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2);},easeFrom: function(pos) {return Math.pow(pos, 4);},easeTo: function(pos) {return Math.pow(pos, 0.25);},linear: function(pos) {return pos},sinusoidal: function(pos) {return ( - Math.cos(pos * Math.PI) / 2) + 0.5;},reverse: function(pos) {return 1 - pos;},mirror: function(pos, transition) {transition = transition || tween.sinusoidal;if (pos < 0.5) return transition(pos * 2);else return transition(1 - (pos - 0.5) * 2);},flicker: function(pos) {var pos = pos + (Math.random() - 0.5) / 5;return tween.sinusoidal(pos < 0 ? 0 : pos > 1 ? 1 : pos);},wobble: function(pos) {return ( - Math.cos(pos * Math.PI * (9 * pos)) / 2) + 0.5;},pulse: function(pos, pulses) {return ( - Math.cos((pos * ((pulses || 5) - .5) * 2) * Math.PI) / 2) + .5;},blink: function(pos, blinks) {return Math.round(pos * (blinks || 5)) % 2;},spring: function(pos) {return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp( - pos * 6));},none: function(pos) {return 0},full: function(pos) {return 1}}
應用:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>無標題文檔</title><style type="text/css">#box {width:400px;height:50px;background:#000;color:#fff;line-height:50px;}</style><script type="text/javascript" src="tween.js"></script><script type="text/javascript">function ani() {this.init.apply(this, arguments)}ani.prototype = {init: function(el) {el = typeof el == 'string' ? document.getElementById(el) : el;this.fx(100, 600,function(x) {el.style.width = x + 'px';},function() {alert('oh yeah');});},fx: function(f, t, fn, callback) {var D = Date,d = new D,e, T = 500,F = function(x) {return tween.bounce(x);}return e = setInterval(function() {var z = Math.min(1, (new D - d) / T);if (false === fn( + f + (t - f) * F(z)) || z == 1) {if (callback && typeof callback == 'function') callback();clearInterval(e);}},10);},fx2: function(b, c, fn, callback) {var d = 50,t = 0,F = function(t, b, c, d) {return Tween.Bounce.easeOut(t, b, c, d)}var e = setInterval(function() {t++;if (false === fn(F(t, b, c, d)) || t == d) {if (callback && typeof callback == 'function') callback();clearInterval(e)}},10);}}window.onload = function() {var box = document.getElementById('box');box.onclick = function() {new ani(this);}}</script></head><body><div id="box">輕輕的點我一下。</div></body></html>
PS:這裡有兩個tween類.兩個公式的效果差不多,只不過他們傳得參數不一樣,我簡單的寫了個應用,統一了一下用法。如果數學不好的話,公式就不要去研究了,就像我一樣,直接拿來用就可以了。