javascript
javascript的缓动效果
這部分對原先的緩動函數進行抽象化,并結合緩動公式進行強化。成品的效果非常驚人逆天。走過路過不要錯過。
好了,打諢到此為止。普通的加速減速是難以讓人滿意的,為了實現彈簧等讓人眼花繚亂的效果必須動用緩動公式。我見過兩套緩動公式,一套是早期Robert Penner大神的緩動公式,內置到tween類中,不過現在人們越來越推薦tweenlite這個新秀了。另一套是script.aculo.us與mootools里面的,由于mootools可稱之為prototype的升級版,script.aculo.us則是基于prototype,我們就把它們并稱為prototype流派。與flash流派最大的不同是,它們封裝得更好,并只需傳入一個參數(0~1的小數),并且擁有嚴密的隊列機制來調用各種回調函數。如在回調函數設置元素的長寬,就弄成Scale特效,利用它我們進一步制作SlideUp,SlideDown,Squish等復合特效。
我們先來看flash流派的緩動公式,它們基本都有如下四個參數。
- t:timestamp,指緩動效果開始執行到當前幀開始執行時經過的時間段,單位ms
- b:beginning position,起始位置
- c:change,要移動的距離,就是終點位置減去起始位置。
- d: duration ,緩和效果持續的時間。
我們把這四個參數傳入Robert Penner大神的緩動公式,它就會計算出當前幀物體移動的位置。我們對比原來的函數來改寫。
var transition = function(el){transition.linear = function(t,b,c,d){ return c*t/d + b; };//免費提供一個緩動公式(勻速運動公式)el.style.position = "absolute";var options = arguments[1] || {},begin = getCoords(el).left,//開始位置change = parseFloat(getStyle(_("taxiway"),"width")) - parseFloat(getStyle(el,"width")),//要移動的距離duration = options.duration || 500,//緩動效果持續時間ease = options.ease || transition.linear,//要使用的緩動公式end = begin + change,//結束位置startTime = new Date().getTime();//開始執行的時間(function(){setTimeout(function(){var newTime = new Date().getTime(),//當前幀開始的時間timestamp = newTime - startTime;//逝去時間el.style.left = ease(timestamp,begin,change,duration) + "px";//移動if(duration <= timestamp){el.style.left = end + "px";}else{setTimeout(arguments.callee,25);//每移動一次停留25毫秒 }},25)})() }接著是各種緩動公式大閱兵,共分為十一大類,除了linear。其他類又分為三種。
- easeIn方法控制補間如何從開始到最高速度。
- easeOut 方法控制補間減速并停在目標位置
- easeInOut方法同時控制上述兩者。
具體公式見下面(共31種)。
//***********@author:Robert Penner and cloudgamer************* //http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.htmlvar 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;}}} <div id="taxiway"><div id="move" onclick="transition(this,{ease:Tween.Bounce.easeOut})"></div> </div>但我不喜歡flash流派的緩動公式,為了使用prototype流派的緩動公式,我進一步改進與抽象化我的緩動函數
//******************@author : 司徒正美************var transition = function(el){el.style.position = "absolute";var options = arguments[1] || {},begin = options.begin,//開始位置change = options.change,//變化量duration = options.duration || 500,//緩動效果持續時間field = options.field,//必須指定,基本上對top,left,width,height這個屬性進行設置ftp = options.ftp || 50,onStart = options.onStart || function(){},onEnd = options.onEnd || function(){},ease = options.ease,//要使用的緩動公式end = begin + change,//結束位置startTime = new Date().getTime();//開始執行的時間 onStart();(function(){setTimeout(function(){var newTime = new Date().getTime(),//當前幀開始的時間timestamp = newTime - startTime,//逝去時間delta = ease(timestamp / duration);el.style[field] = Math.ceil(begin + delta * change) + "px"if(duration <= timestamp){el.style[field] = end + "px";onEnd();}else{setTimeout(arguments.callee,1000/ftp); }},1000/ftp) })()}| el | element | 必需,為頁面元素 |
| begin | number | 必需,開始的位置 |
| change | number | 必需,要移動的距離 |
| duration | number | 可選,緩動效果持續時間,默認是500ms。建議取300~1000ms。 |
| field | string | 必需,要發生變化的樣式屬性。請在top,left,bottom,right,width與height中選擇。 |
| ftp | number | 可選,每秒進行多少幀動畫,默認50幀,保證流暢播放。一些參考資料,日本動畫1秒36幀,中國卡通24幀,賽車游戲60幀。 |
| ease | function | 必需,緩動公式,參數為0~1之間的數。可參考我下面給出的45條公式。 |
| onStart | function | 可選,在開始時執行。 |
| onEnd | function | 可選,在結束時執行。 |
prototype流派的緩動公式,只需一個參數(增至45種)
?
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);elsereturn 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> <html dir="ltr" lang="zh-CN"><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=8"><style type="text/css">.taxiway{width:800px;height:100px;background:#E8E8FF;}.move{width:100px;height:100px;background:#a9ea00;}#panel {float:left;width:810px}#panel div{float:left;width:88px;border:1px solid #333;height:20px;font-size:11px;}div.transition {margin-top: 30px;width: 200px;height: 200px;position: relative;margin-bottom:10px;}div.transition div {position: absolute;height: 1px;width: 1px;background: #000;}div.transition span {display: block;position: absolute;border-bottom: 1px solid #dadada;font-size: 10px;color: #888;width: 200px;left: 0px;}div.transition div#indicator {position:absolute;background-color:#a9ea00;height: 200px;top: 0px;left: 0px;}div.transition div#marker {background-color: #f00;height: 6px;width: 6px;border-radius: 3px;-webkit-border-radius: 3px;-moz-border-radius: 3px;left: 0px;margin-bottom: -3px;margin-left: -3px;}div.transition div#label {background: transparent;color: #ABD474;font-size: 20px;height: 20px;width: 200px;text-align: center;top: 80px;left: 0px;z-index: -1;}</style><script type="text/javascript">var getCoords = function(el){var box = el.getBoundingClientRect(),doc = el.ownerDocument,body = doc.body,html = doc.documentElement,clientTop = html.clientTop || body.clientTop || 0,clientLeft = html.clientLeft || body.clientLeft || 0,top = box.top + (self.pageYOffset || html.scrollTop || body.scrollTop ) - clientTop,left = box.left + (self.pageXOffset || html.scrollLeft || body.scrollLeft) - clientLeftreturn { 'top': top, 'left': left };};var getStyle = function(el, style){if(!+"\v1"){style = style.replace(/\-(\w)/g, function(all, letter){return letter.toUpperCase();});var value = el.currentStyle[style];(value == "auto")&&(value = "0px" );return value;}else{return document.defaultView.getComputedStyle(el, null).getPropertyValue(style)}}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);elsereturn 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}}var _ = function(id){return document.getElementById(id);}var transition = function(el){el.style.position = "absolute";var options = arguments[1] || {},begin = options.begin,//開始位置 change = options.change,//變化量 duration = options.duration || 500,//緩動效果持續時間 field = options.field,//必須指定,基本上對top,left,width,height這個屬性進行設置 ftp = options.ftp || 50,onEnd = options.onEnd || function(){},ease = options.ease,//要使用的緩動公式 end = begin + change,//結束位置 startTime = new Date().getTime();//開始執行的時間 (function(){setTimeout(function(){var newTime = new Date().getTime(),//當前幀開始的時間 timestamp = newTime - startTime,//逝去時間 delta = ease(timestamp / duration);el.style[field] = Math.ceil(begin + delta * change) + "px"if(duration <= timestamp){el.style[field] = end + "px";onEnd();}else{setTimeout(arguments.callee,1000/ftp); }},1000/ftp) })()}if (typeof Array.prototype['max'] == 'undefined') {Array.prototype.map = function(fn, thisObj) {var scope = thisObj || window;var a = [];for ( var i=0, j=this.length; i < j; ++i ) {a.push(fn.call(scope, this[i], i, this));}return a;};Array.prototype.max = function(){return Math.max.apply({},this)}Array.prototype.min = function(){return Math.min.apply({},this)}}var range = function(start,end){var _range = []for(var i = start,l=end-start;i<l;i++){_range.push(i)}return _range}var draw = function(ease){var demo = _("transition");demo.innerHTML = "";//還原!//***********繪制控制臺********************var values = range(0,200).map(function(v){return tween[ease](v/200) * 200; }),max = Math.max(200, values.max()),min = Math.min(0, values.min());if (min==max) {min = 0;max = 200;}var factor = 200/(max-min), grid = '<span style="bottom:'+Math.round((0-min)*factor)+'px">0</span>'+'<span style="bottom:'+Math.round((200-min)*factor)+'px">1</span>',graph = range(0,200).map(function(v){return '<div style="left:'+v+'px;bottom:'+Math.round((values[v]-min)*factor)+'px;height:1px"></div>';}).join('') + '<div id="indicator" style="display:none">'+'</div><div id="marker" style="display:none"></div><div id="label"></div>';demo.innerHTML = grid + graph;var indicator = _("indicator"),marker = _("marker"),label = _("label"),demoTransition = function(pos){var value = tween[ease](pos);indicator.style.display = "block";marker.style.display = "block";marker.style.left = Math.round(pos*200)+'px';marker.style.bottom = Math.round((value*200-min)*factor)+'px';label.innerHTML = Math.round(pos*200)+'px';return value;}transition(indicator,{field:"left",begin:parseFloat(getCoords(demo).left),change:200,ease:demoTransition})}window.onload = function(){var panelHTML = function(){var builder = [];var _temp = 'Back Circ Cubic Expo Quad Quart Quint Sine'.split(' ');var ease = _temp.map(function(v){return 'easeIn'+v;});ease = ease.concat(_temp.map(function(v){return 'easeOut'+v;}));ease = ease.concat(_temp.map(function(v){return 'easeInOut'+v;}));ease = ease.concat('blink bounce bouncePast easeFrom easeFromTo easeOutBounce easeTo elastic'.split(' '));ease = ease.concat('flicker full linear mirror none pulse reverse sinusoidal spring swingTo swingFrom swingFromTo wobble'.split(' '))for(var i =0,l=ease.length;i<l;i++){builder.push("<div οnclick='draw(this.innerHTML)'>");builder.push(ease[i]);builder.push("</div>");}return builder.join('');}var panel = document.createElement("div");panel.id = "panel"panel.innerHTML = panelHTML();_("transition").parentNode.insertBefore(panel,_("transition").nextSibling);}</script><title>緩動BY司徒正美</title></head><body><div class="taxiway"><div class="move" onclick="transition(this,{field:'left',begin:parseFloat(getCoords(this).left),change:700,ease:tween.bouncePast})"></div></div><div class="taxiway"><div class="move" onclick="transition(this,{field:'width',begin:parseFloat(getStyle(this,'width')),change:300,ease:tween.spring})"></div></div> <span class="clear"></span> <h2>請點擊下表的格子</h2><div id="transition" class="transition"></div></body> </html>除了這45條公式外,我們還可以制定自己的緩動公式。正如我在上面表格中提到, 它在運行過程是不執行回調函數時,但你們可以在運行框中看到,我可以實現一邊移動一邊記錄點的坐標。這是怎樣實現的呢? 我們只要把上面的緩動公式的任何一條塞進一個只有一個參數的函數就行了。當然此函數要有返回,供繼續向下調用。以下就是一個模板:
var myTween = function(pos){ //緩動公式var value = tween[ease](pos);//***********這上面是固定的**************indicator.style.display = "block";marker.style.display = "block";marker.style.left = Math.round((pos*200))+'px';marker.style.bottom = Math.round(((value*200)-min)*factor)+'px';label.innerHTML = Math.round((pos*200))+'px';//************這下面是固定的*************return value;} <div class="taxiway"><div class="move" onclick="transition(this,{field:'left',begin:parseFloat(getCoords(this).left),change:700,ease:tween.bouncePast})"></div> </div> <div class="taxiway"><div class="move" onclick="transition(this,{field:'width',begin:parseFloat(getStyle(this,'width')),change:300,ease:tween.spring})"></div> </div>http://www.cnblogs.com/rubylouvre/archive/2009/09/17/1567607.html
?
總結
以上是生活随笔為你收集整理的javascript的缓动效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: T-sql 查询
- 下一篇: FTP服务器的安装和配置