<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Ruby's Louvre

      每天學(xué)習(xí)一點(diǎn)點(diǎn)算法

      導(dǎo)航

      javascript的緩動(dòng)效果(第2部分)

      這部分對(duì)原先的緩動(dòng)函數(shù)進(jìn)行抽象化,并結(jié)合緩動(dòng)公式進(jìn)行強(qiáng)化。成品的效果非常驚人逆天。走過(guò)路過(guò)不要錯(cuò)過(guò)。

      好了,打諢到此為止。普通的加速減速是難以讓人滿意的,為了實(shí)現(xiàn)彈簧等讓人眼花繚亂的效果必須動(dòng)用緩動(dòng)公式。我見過(guò)兩套緩動(dòng)公式,一套是早期Robert Penner大神的緩動(dòng)公式,內(nèi)置到tween類中,不過(guò)現(xiàn)在人們?cè)絹?lái)越推薦tweenlite這個(gè)新秀了。另一套是script.aculo.us與mootools里面的,由于mootools可稱之為prototype的升級(jí)版,script.aculo.us則是基于prototype,我們就把它們并稱為prototype流派。與flash流派最大的不同是,它們封裝得更好,并只需傳入一個(gè)參數(shù)(0~1的小數(shù)),并且擁有嚴(yán)密的隊(duì)列機(jī)制來(lái)調(diào)用各種回調(diào)函數(shù)。如在回調(diào)函數(shù)設(shè)置元素的長(zhǎng)寬,就弄成Scale特效,利用它我們進(jìn)一步制作SlideUp,SlideDown,Squish等復(fù)合特效。

      我們先來(lái)看flash流派的緩動(dòng)公式,它們基本都有如下四個(gè)參數(shù)。

      • t:timestamp,指緩動(dòng)效果開始執(zhí)行到當(dāng)前幀開始執(zhí)行時(shí)經(jīng)過(guò)的時(shí)間段,單位ms
      • b:beginning position,起始位置
      • c:change,要移動(dòng)的距離,就是終點(diǎn)位置減去起始位置。
      • d: duration ,緩和效果持續(xù)的時(shí)間。

      我們把這四個(gè)參數(shù)傳入Robert Penner大神的緩動(dòng)公式,它就會(huì)計(jì)算出當(dāng)前幀物體移動(dòng)的位置。我們對(duì)比原來(lái)的函數(shù)來(lái)改寫。

        var transition = function(el){
          transition.linear = function(t,b,c,d){ return c*t/d + b; };//免費(fèi)提供一個(gè)緩動(dòng)公式(勻速運(yùn)動(dòng)公式)
          el.style.position = "absolute";
          var options = arguments[1] || {},
          begin =  getCoords(el).left,//開始位置
          change = parseFloat(getStyle(_("taxiway"),"width")) - parseFloat(getStyle(el,"width")),//要移動(dòng)的距離
          duration = options.duration || 500,//緩動(dòng)效果持續(xù)時(shí)間
          ease = options.ease || transition.linear,//要使用的緩動(dòng)公式
          end = begin + change,//結(jié)束位置
          startTime = new Date().getTime();//開始執(zhí)行的時(shí)間
          (function(){
            setTimeout(function(){
              var newTime = new Date().getTime(),//當(dāng)前幀開始的時(shí)間
              timestamp = newTime - startTime;//逝去時(shí)間
              el.style.left = ease(timestamp,begin,change,duration) + "px";//移動(dòng)
              if(duration <= timestamp){
                el.style.left = end + "px";
              }else{
                setTimeout(arguments.callee,25);//每移動(dòng)一次停留25毫秒
              }
            },25)
          })()
        }
      

      接著是各種緩動(dòng)公式大閱兵,共分為十一大類,除了linear。其他類又分為三種。

      • easeIn方法控制補(bǔ)間如何從開始到最高速度。
      • easeOut 方法控制補(bǔ)間減速并停在目標(biāo)位置
      • easeInOut方法同時(shí)控制上述兩者。

      具體公式見下面(共31種)。

      //***********@author:Robert Penner and cloudgamer*************
      //http://www.rzrgm.cn/cloudgamer/archive/2009/01/06/Tween.html
        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;
            }
          }
        }
      
      <div id="taxiway">
        <div id="move" onclick="transition(this,{ease:Tween.Bounce.easeOut})"></div>
      </div>
      

      但我不喜歡flash流派的緩動(dòng)公式,為了使用prototype流派的緩動(dòng)公式,我進(jìn)一步改進(jìn)與抽象化我的緩動(dòng)函數(shù)

      //******************@author : 司徒正美************
        var transition = function(el){
          el.style.position = "absolute";
          var options = arguments[1] || {},
          begin =  options.begin,//開始位置
          change = options.change,//變化量
          duration = options.duration || 500,//緩動(dòng)效果持續(xù)時(shí)間
          field = options.field,//必須指定,基本上對(duì)top,left,width,height這個(gè)屬性進(jìn)行設(shè)置
          ftp = options.ftp || 50,
          onStart = options.onStart || function(){},
          onEnd = options.onEnd || function(){},
          ease = options.ease,//要使用的緩動(dòng)公式
          end = begin + change,//結(jié)束位置
          startTime = new Date().getTime();//開始執(zhí)行的時(shí)間
          onStart();
          (function(){
            setTimeout(function(){
              var newTime = new Date().getTime(),//當(dāng)前幀開始的時(shí)間
              timestamp = newTime - startTime,//逝去時(shí)間
              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)
          })()
        }
      
      參數(shù) 類型 說(shuō)明
      el element 必需,為頁(yè)面元素
      begin number 必需,開始的位置
      change number 必需,要移動(dòng)的距離
      duration number 可選,緩動(dòng)效果持續(xù)時(shí)間,默認(rèn)是500ms。建議取300~1000ms。
      field string 必需,要發(fā)生變化的樣式屬性。請(qǐng)?jiān)趖op,left,bottom,right,width與height中選擇。
      ftp number 可選,每秒進(jìn)行多少幀動(dòng)畫,默認(rèn)50幀,保證流暢播放。一些參考資料,日本動(dòng)畫1秒36幀,中國(guó)卡通24幀,賽車游戲60幀。
      ease function 必需,緩動(dòng)公式,參數(shù)為0~1之間的數(shù)??蓞⒖嘉蚁旅娼o出的45條公式。
      onStart function 可選,在開始時(shí)執(zhí)行。
      onEnd function 可選,在結(jié)束時(shí)執(zhí)行。

      prototype流派的緩動(dòng)公式,只需一個(gè)參數(shù)(增至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);
            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
          }
        }
      

      除了這45條公式外,我們還可以制定自己的緩動(dòng)公式。正如我在上面表格中提到, 它在運(yùn)行過(guò)程是不執(zhí)行回調(diào)函數(shù)時(shí),但你們可以在運(yùn)行框中看到,我可以實(shí)現(xiàn)一邊移動(dòng)一邊記錄點(diǎn)的坐標(biāo)。這是怎樣實(shí)現(xiàn)的呢? 我們只要把上面的緩動(dòng)公式的任何一條塞進(jìn)一個(gè)只有一個(gè)參數(shù)的函數(shù)就行了。當(dāng)然此函數(shù)要有返回,供繼續(xù)向下調(diào)用。以下就是一個(gè)模板:

        var myTween = function(pos){ //緩動(dòng)公式
            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>
      

      posted on 2009-09-17 04:18  司徒正美  閱讀(12533)  評(píng)論(34)    收藏  舉報(bào)

      主站蜘蛛池模板: 亚洲第一福利网站在线观看| 亚洲AV日韩AV综合在线观看| 亚欧洲乱码视频一二三区| 中文字幕乱码一区二区免费| 久久香蕉国产线看观看猫咪av| 小嫩批日出水无码视频免费| 欧美日本一区二区视频在线观看| 国产亚洲精品国产福APP| 潢川县| 国产成人精品无人区一区| 久热这里只有精品12| 国产精品va在线观看无码| 97在线碰| 国产激情一区二区三区四区 | 国产成人精品2021欧美日韩| 国产精品美女一区二区三| 日韩精品一区二区三区蜜臀| 国产首页一区二区不卡| 欧美不卡无线在线一二三区观| 18禁无遮挡啪啪无码网站| 在线免费观看视频1区| 亚洲av午夜成人片| 婷婷综合缴情亚洲| 亚洲av无码成人精品区一区| 色窝窝免费播放视频在线| 日韩精品福利视频在线观看| 亚洲精品一区二区口爆| 日本丰满熟妇videossex一| 欧美精欧美乱码一二三四区 | 亚洲V天堂V手机在线| 国产色婷婷精品综合在线| 国产自拍偷拍视频在线观看 | 亚洲国产激情一区二区三区| 国产精品国三级国产av| 特级aaaaaaaaa毛片免费视频| 午夜精品一区二区三区成人| 国产成人无码免费视频在线| 日本肥老妇色xxxxx日本老妇| 九九热免费在线播放视频| 国产午夜影视大全免费观看| 天堂а√8在线最新版在线|