第八周第三天筆記之運動庫封裝

運動庫封裝

  • 實質(zhì):一個元素從當前位置(ele決定)開始,在規(guī)定的時間(duration)內(nèi),以一種運動效果(effect)递雀,到達目標位置(target),然后做一件事情(callback)蚀浆。是一個運動過程缀程。
  • 思路:
    1. 自執(zhí)行函數(shù)封裝,建立運動形式庫gbEffect市俊,創(chuàng)建運動函數(shù)animate()杨凑;
    2. animate傳入一個參數(shù)opt,為一個對象摆昧,實參對象中包含多個屬性名撩满,如:ele,duration,target對象,effect,callback等屬性绅你;
    3. animate函數(shù)創(chuàng)建流程:
      • 1 對傳入的實參值進行判斷鹦牛;
      • 2 新建一個對象,里面添加默認樣式
      • 3 將傳入的實參opt勇吊,所有屬性賦值給defaultOpt,如果存在重新賦值窍仰,如果不存在汉规,使用默認值;
      • 4 獲取defaultOpt里面的參數(shù)
      • 5 獲取運動形式驹吮,計算參數(shù)
        • 5.1 獲取運動形式:判斷effect的數(shù)據(jù)類型针史,滿足下面兩種情況,就執(zhí)行各自的代碼碟狞,如果不滿足啄枕,就使用默認值;
        • 5.2 計算傳入運動形式中的參數(shù)
      • 6 添加定時器
        • 6.1 變量累加
        • 6.2 邊界值判斷
          • 6.2.1 設(shè)置邊界值
          • 6.2.2 停止定時器
          • 6.2.3 執(zhí)行回調(diào)函數(shù)族沃,進行下一步操作
          • 6.2.4 阻斷程序執(zhí)行
        • 6.3 獲取最新位置及設(shè)置最新位置
          • 6.3.1 運動方式獲取最新位置频祝;
          • 6.3.2 分別設(shè)置最新位置
    4. 將自執(zhí)行函數(shù)中的animate函數(shù)設(shè)置為window的全局變量泌参;
  • 知識點:
    • 判斷是否傳入實參,并判斷實參中是否傳入元素常空,如以下代碼:
     function animate(opt) {
         //判斷是否傳入實參
         opt=opt || {};
         //ele和target為必須傳的參數(shù)沽一,所以只要有一個不存在就停止代碼執(zhí)行;
         if(!opt.ele || !opt.target) return;//如果傳參錯誤漓糙,代碼阻斷不執(zhí)行铣缠;
       }
    
    • 新建一個新的defaultOpt對象,里面設(shè)置默認的屬性昆禽,再將傳入的對象的每個屬性賦值給新的對象蝗蛙,如果屬性已存在,則重新賦值醉鳖,如果不存在則設(shè)置捡硅;defaultOpt的作用是設(shè)置默認的屬性,如果傳入的實參里面設(shè)置了defaultOpt里面的屬性辐棒,就重新賦值病曾,如果沒有設(shè)置,就用默認值漾根;
     //1 新建一個對象泰涂,里面添加默認樣式
     var defaultOpt={
         duration: 2000,
         effect: "linear"
     };
     //2 將傳入的實參opt,所有屬性賦值給defaultOpt辐怕,如果存在重新賦值逼蒙,如果不存在,使用默認值寄疏;
     for(var attr in opt){
         defaultOpt[attr]=opt[attr];
     }
     //總結(jié):defaultOpt的作用是設(shè)置默認的屬性是牢,如果傳入的實參里面設(shè)置了defaultOpt里面的屬性,就重新賦值陕截,如果沒有設(shè)置驳棱,就用默認值;
     //下面所有代碼不再使用opt农曲,而使用defaultOpt;
    
    • 回調(diào)函數(shù)調(diào)用及改變this指向的設(shè)置社搅,如:callback && callback.call(ele);利用"&&"來作判斷乳规,當callback存在的情況下形葬,才會執(zhí)行后面代碼,后面代碼中利用call來改變了回調(diào)函數(shù)中的this指向暮的,使其指向ele元素笙以,默認情況下,this指向window;
    • 透明度的設(shè)置問題冻辩,在target中設(shè)置透明度后猖腕,在運動形式中計算完輸出的是字符串拆祈,不能設(shè)置成功,所以需要處理一下谈息,利用Number進行轉(zhuǎn)化缘屹;
     //處理opacity的問題,屬性值獲取的都是字符串侠仇,不能設(shè)置成功
     if(typeof linear ==="string"){
          //linear=parseFloat(linear).toFixed(2);//此時轉(zhuǎn)換后還是字符串
         linear=Number(linear.slice(0,4));//此時轉(zhuǎn)化后為數(shù)字轻姿,必須先截取在轉(zhuǎn)化,直接用Number轉(zhuǎn)化會變成NaN;
     }
    
  • 代碼
    • 運動庫代碼:
     (function () {
         //運動形式庫
         function animate(opt) {
             //0 對傳入的實參值進行判斷逻炊;
             opt=opt || {};
             //ele和target為必須傳的參數(shù)互亮,所以只要有一個不存在就停止代碼執(zhí)行;
             if(!opt.ele || !opt.target) return;//如果傳參錯誤余素,代碼阻斷不執(zhí)行豹休;
             //1 新建一個對象,里面添加默認樣式
             var defaultOpt={
                 duration: 2000,
                 effect: "Linear"
             };
             //2 將傳入的實參opt桨吊,所有屬性賦值給defaultOpt威根,如果存在重新賦值,如果不存在视乐,使用默認值洛搀;
             for(var attr in opt){
                 defaultOpt[attr]=opt[attr];
             }
             //總結(jié):defaultOpt的作用是設(shè)置默認的屬性,如果傳入的實參里面設(shè)置了defaultOpt里面的屬性佑淀,就重新賦值留美,如果沒有設(shè)置,就用默認值伸刃;
             //下面所有代碼不再使用opt谎砾,而使用defaultOpt;
     
             //3 獲取defaultOpt里面的參數(shù)
             var ele=defaultOpt.ele;
             var target=defaultOpt.target;
             var duration=defaultOpt.duration;
             var callback=defaultOpt.callback;
             var effect=defaultOpt.effect;
             var tempEffect=null;
             //4 獲取運動形式,計算參數(shù)
             //4.1 獲取運動形式:判斷effect的數(shù)據(jù)類型捧颅,滿足下面兩種情況景图,就執(zhí)行各自的代碼,如果不滿足碉哑,就使用默認值挚币;
             var ary=["Linear","EaseIn","EaseOut","EaseBoth","EaseInStrong","EaseOutStrong","EaseBothStrong","Elastic-In","Elastic-Out","Elastic-Both","Back-In","Back-Out","Back-Both","Bounce-In","Bounce-Out","Bounce-Both"];
             if(typeof effect==="number"){
                 ary=ary[effect%ary.length].split("-");
                 tempEffect=ary.length>=2?gbEffect[ary[0]][ary[1]]:gbEffect[ary[0]];
             }else if(typeof effect==="object"){
                 tempEffect=effect.length>=2?gbEffect[effect[0]][effect[1]]:gbEffect[effect[0]];
             }else if(typeof effect==="string"){
                 tempEffect=gbEffect[effect];//此時tempEffect設(shè)置一個函數(shù)定義地址,不是函數(shù)名谭梗;
             }
             //4.2 計算傳入運動形式中的參數(shù)
             var begin={},change={};
             for(var attr in target){
                 begin[attr]=utils.css(ele,attr);
                 change[attr]=target[attr]-begin[attr];
             }
             var time=0;
     
             //5 添加定時器
             var timer=setInterval(function () {
                 //5.1 變量累加
                 time+=30;
                 //5.2 邊界值判斷
                 if(time>=duration){
                     //5.2.1 設(shè)置邊界值
                     utils.css(ele,target);
                     //5.2.2 停止定時器
                     clearInterval(timer);
                     //5.2.3 執(zhí)行回調(diào)函數(shù),進行下一步操作
                     callback && callback.call(ele);//當callback存在的時候宛蚓,執(zhí)行回調(diào)函數(shù)激捏,改變其中的this指向為元素;
                     //5.2.4 阻斷程序執(zhí)行
                     return;
                 }
                 //5.3 獲取最新位置及設(shè)置最新位置
                 for(var attr in change){
                     //5.3.1 運動方式獲取最新位置凄吏;
                     var cur=tempEffect(time,begin[attr],change[attr],duration);
                     //處理opacity的問題远舅,屬性值獲取的都是字符串闰蛔,不能設(shè)置成功
                     if(typeof cur ==="string"){
                         //cur=parseFloat(cur).toFixed(2);//此時轉(zhuǎn)換后還是字符串
                         cur=Number(cur.slice(0,4));//此時轉(zhuǎn)化后為數(shù)字
                     }
                     //5.3.2 分別設(shè)置最新位置
                     utils.css(ele,attr,cur);
                 }
             },30)
     
         }
         window.animate=animate;//將私有函數(shù)設(shè)置為全局變量;
     })();
    
    • 運動方式庫:
     var gbEffect= {
         Linear: function (t, b, c, d){  //勻速
             return c*t/d + b;
         },
         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;
         },
         EaseBoth: function(t, b, c, d){  //加速減速曲線
             if ((t/=d/2) < 1) {
                 return c/2*t*t + b;
             }
             return -c/2 * ((--t)*(t-2) - 1) + b;
         },
         EaseInStrong: function(t, b, c, d){  //加加速曲線
             return c*(t/=d)*t*t*t + b;
         },
         EaseOutStrong: function(t, b, c, d){  //減減速曲線
             return -c * ((t=t/d-1)*t*t*t - 1) + b;
         },
         EaseBothStrong: 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;
         },
         Elastic:{
             In: function(t, b, c, d, a, p){  //正弦衰減曲線(彈動漸入)
                 if (t === 0) {
                     return b;
                 }
                 if ( (t /= d) == 1 ) {
                     return b+c;
                 }
                 if (!p) {
                     p=d*0.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;
             },
             Out: function(t, b, c, d, a, p){    //正弦增強曲線(彈動漸出)
                 if (t === 0) {
                     return b;
                 }
                 if ( (t /= d) == 1 ) {
                     return b+c;
                 }
                 if (!p) {
                     p=d*0.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;
             },
             Both: function(t, b, c, d, a, p){
                 if (t === 0) {
                     return b;
                 }
                 if ( (t /= d/2) == 2 ) {
                     return b+c;
                 }
                 if (!p) {
                     p = d*(0.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 - 0.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 )*0.5 + c + b;
             }
     
         },
         Back:{
             In: function(t, b, c, d, s){     //回退加速(回退漸入)
                 if (typeof s == 'undefined') {
                     s = 1.70158;
                 }
                 return c*(t/=d)*t*((s+1)*t - s) + b;
             },
             Out: function(t, b, c, d, s){
                 if (typeof s == 'undefined') {
                     s = 3.70158;  //回縮的距離
                 }
                 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
             },
             Both: function(t, b, c, d, s){
                 if (typeof 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:{
             In: function(t, b, c, d){    //彈球減振(彈球漸出)
                 return c - gbEffect.Bounce.Out(d-t, 0, c, d) + b;
             },
             Out: 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 + 0.75) + b;
                 } else if (t < (2.5/2.75)) {
                     return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
                 }
                 return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
             },
             Both: function(t, b, c, d){
                 if (t < d/2) {
                     return gbEffect.Bounce.In(t*2, 0, c, d) * 0.5 + b;
                 }
                 return gbEffect.Bounce.Out(t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
             }
         }
     };
     //下列數(shù)組元素為所有的函數(shù)名图柏;
     var gbEffectAry=["Linear","EaseIn","EaseOut","EaseBoth","EaseInStrong","EaseOutStrong","EaseBothStrong","Elastic-In","Elastic-Out","Elastic-Both","Back-In","Back-Out","Back-Both","Bounce-In","Bounce-Out","Bounce-Both"];
    
    • 執(zhí)行代碼:
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>運動庫封裝終極版</title>
         <style>
             *{
                 margin: 0;
                 padding: 0;
             }
             #div1{
                 width: 80px;
                 height: 80px;
                 background-color: red;
                 line-height: 80px;
                 text-align: center;
                 position: absolute;
                 top: 10px;
                 left:200px;
                 opacity: 0.1;
                 filter: alpha(opacity=10);
             }
             #div2{
                 width: 1px;
                 height: 500px;
                 margin-top: 10px;
                 background-color: blue;
                 position: absolute;
                 top: 10px;
                 left: 1100px;
             }
         </style>
     </head>
     <body>
     <div id="div1">物體</div>
     <div id="div2"></div>
     <script src="utils.js"></script>
     <script src="moveEffect.js"></script>
     <script src="01運動庫封裝終極版.js"></script>
     <script>
         var oDiv1=document.getElementById("div1");
         animate({
             ele:oDiv1,
             target:{
                 left:1000,
                 top:400,
                 opacity: 0.8
             },
             effect:1,
             duration: 2000,
             callback:function () {
                 //默認情況下回調(diào)函數(shù)執(zhí)行時序六,this指向window;
                 //在調(diào)用時,用call改變this指向為ele蚤吹;
                 this.style.backgroundColor="yellow";
             }
         })
     </script>
     </body>
     </html>
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末例诀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子裁着,更是在濱河造成了極大的恐慌繁涂,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件二驰,死亡現(xiàn)場離奇詭異扔罪,居然都是意外死亡,警方通過查閱死者的電腦和手機桶雀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門矿酵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人矗积,你說我怎么就攤上這事全肮。” “怎么了漠魏?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵倔矾,是天一觀的道長。 經(jīng)常有香客問我柱锹,道長哪自,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任禁熏,我火速辦了婚禮壤巷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞧毙。我一直安慰自己胧华,他們只是感情好,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布宙彪。 她就那樣靜靜地躺著矩动,像睡著了一般。 火紅的嫁衣襯著肌膚如雪释漆。 梳的紋絲不亂的頭發(fā)上悲没,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音男图,去河邊找鬼示姿。 笑死甜橱,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的栈戳。 我是一名探鬼主播岂傲,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼子檀!你這毒婦竟也來了镊掖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤命锄,失蹤者是張志新(化名)和其女友劉穎堰乔,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脐恩,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡镐侯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驶冒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苟翻。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骗污,靈堂內(nèi)的尸體忽然破棺而出崇猫,到底是詐尸還是另有隱情,我是刑警寧澤需忿,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布诅炉,位于F島的核電站,受9級特大地震影響屋厘,放射性物質(zhì)發(fā)生泄漏涕烧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一汗洒、第九天 我趴在偏房一處隱蔽的房頂上張望议纯。 院中可真熱鬧,春花似錦溢谤、人聲如沸瞻凤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阀参。三九已至,卻和暖如春瞻坝,著一層夾襖步出監(jiān)牢的瞬間蛛壳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留炕吸,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓勉痴,卻偏偏與公主長得像赫模,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蒸矛,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容