Javascript 完美運(yùn)動(dòng)框架(逐行分析代碼,讓你輕松了運(yùn)動(dòng)的原理)
大家一聽(tīng)這名字就知道,有了這套框架 網(wǎng)上的效果基本都是可以實(shí)現(xiàn)的。實(shí)際上之前的運(yùn)動(dòng)框架還是有局限性的,就是不能讓好幾個(gè)值一塊運(yùn)動(dòng)。
那這個(gè)問(wèn)題怎么解決呢? 我們先來(lái)看看之前的運(yùn)動(dòng)框架
function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { return getComputedStyle(obj, null)[name]; } } function startMove(obj, attr, iTarget) { clearInterval(obj.time); obj.time = setInterval(function() { var cur = 0; if (attr == 'opacity') { cur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { cur = parseInt(getStyle(obj, attr)); } var speed = (iTarget - cur) / 6; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if (cur == iTarget) { clearInterval(obj.time); } else { if (attr == 'opacity') { obj.style.filter = 'alpha(opacity=' + cur + speed + ')'; obj.style.opacity = (cur + speed) / 100; } else { obj.style[attr] = cur + speed + 'px'; } } }, 30); }
怎么修改呢? 實(shí)際上很簡(jiǎn)單, 在過(guò)去的框架中,你每一次只能傳一個(gè)樣式,和一個(gè)值。那么現(xiàn)在把這些改成一個(gè)json對(duì)象。相信大家就明白了。
我們調(diào)用的時(shí)候就是startMove(oDiv,{width:200,height:200}); 如果需要的話就在加上回調(diào)函數(shù)。那么我們具體看看代碼是怎么修改的。
function startMove(obj, json, fnEnd) { var MAX=18; //每次調(diào)用就只有一個(gè)定時(shí)器在工作(開始運(yùn)動(dòng)時(shí)關(guān)閉已有定時(shí)器) //并且關(guān)閉或者開啟都是當(dāng)前物體的定時(shí)器,已防止與頁(yè)面上其他定時(shí)器的沖突,使每個(gè)定時(shí)器都互不干擾 clearInterval(obj.timer); obj.timer=setInterval(function (){ var bStop=true; // 假設(shè):所有的值都已經(jīng)到了 for(var name in json) { var iTarget=json[name]; // 目標(biāo)點(diǎn) //處理透明度,不能使用parseInt否則就為0了 if(name=='opacity') { // *100 會(huì)有誤差 0000007 之類的 所以要用 Math.round() 會(huì)四舍五入 var cur=Math.round(parseFloat(getStyle(obj, name))*100); } else { var cur=parseInt(getStyle(obj, name)); // cur 當(dāng)前移動(dòng)的數(shù)值 } var speed=(iTarget-cur)/5; // 物體運(yùn)動(dòng)的速度 數(shù)字越小動(dòng)的越慢 /5 : 自定義的數(shù)字 speed=speed>0?Math.ceil(speed):Math.floor(speed); if(Math.abs(speed)>MAX)speed=speed>0?MAX:-MAX; if(name=='opacity') { obj.style.filter='alpha(opacity:'+(cur+speed)+')'; //IE obj.style.opacity=(cur+speed)/100; //ff chrome } else { obj.style[name]=cur+speed+'px'; } // 某個(gè)值不等于目標(biāo)點(diǎn) if(cur!=iTarget) { bStop=false; } } // 都達(dá)到了目標(biāo)點(diǎn) if(bStop) { clearInterval(obj.timer); if(fnEnd) //只有傳了這個(gè)函數(shù)才去調(diào)用 { fnEnd(); } } }, 20); }
為什么會(huì)有bstop的假設(shè)呢?
其實(shí)如果我這樣調(diào)用startMove(oDiv,{width:101,height:200}); 寬度變成101 已經(jīng)完成運(yùn)動(dòng)了,高度沒(méi)有到, 但是我們可能已經(jīng)關(guān)閉了當(dāng)前的定時(shí)器。運(yùn)動(dòng)已經(jīng)結(jié)束了,就會(huì)出現(xiàn)一個(gè)特殊情況下的bug。解釋一下:
實(shí)際上來(lái)說(shuō),需要所有的運(yùn)動(dòng)都到了才關(guān)閉定時(shí)器,反過(guò)來(lái)說(shuō),如果沒(méi)有不到的,那就關(guān)閉。在程序上就是定義一個(gè)布爾值,一開始為true,假設(shè)
所有的值都已經(jīng)到了,如果說(shuō)有一個(gè)值不等于目標(biāo)點(diǎn),bstop為false 。 在整個(gè)循環(huán)結(jié)束后,bstop 為ture 就說(shuō)明所有運(yùn)動(dòng)都完成了,這個(gè)時(shí)候就關(guān)閉定時(shí)器。
那么這個(gè)運(yùn)動(dòng)框架基本已經(jīng)完成了,適用css2 不適用css3。
總結(jié):
運(yùn)動(dòng)框架的演變過(guò)程
startMove(iTarget) 運(yùn)動(dòng)框架
startMove(obj,iTarget) 多物體
startMove(obj,attr,iTarget) 任意值
startMove(obj,attr,iTarget,fn) 鏈?zhǔn)竭\(yùn)動(dòng)
startMove(obj,json,fn) 完美運(yùn)動(dòng)
O(∩_∩)O謝謝 ~
- js運(yùn)動(dòng)動(dòng)畫的八個(gè)知識(shí)點(diǎn)
- javascript動(dòng)畫之圓形運(yùn)動(dòng),環(huán)繞鼠標(biāo)運(yùn)動(dòng)作小球
- JS運(yùn)動(dòng)框架之分享側(cè)邊欄動(dòng)畫實(shí)例
- 原生javascript實(shí)現(xiàn)勻速運(yùn)動(dòng)動(dòng)畫效果
- js彈性勢(shì)能動(dòng)畫之拋物線運(yùn)動(dòng)實(shí)例詳解
- JS實(shí)現(xiàn)基于Sketch.js模擬成群游動(dòng)的蝌蚪運(yùn)動(dòng)動(dòng)畫效果【附demo源碼下載】
- JS實(shí)現(xiàn)勻速與減速緩慢運(yùn)動(dòng)的動(dòng)畫效果封裝示例
- Js實(shí)現(xiàn)簡(jiǎn)單的小球運(yùn)動(dòng)特效
- javascript實(shí)現(xiàn)10個(gè)球隨機(jī)運(yùn)動(dòng)、碰撞實(shí)例詳解
- JS實(shí)現(xiàn)勻速運(yùn)動(dòng)的代碼實(shí)例
- js實(shí)現(xiàn)緩沖運(yùn)動(dòng)效果的方法
- JS實(shí)現(xiàn)的小火箭發(fā)射動(dòng)畫效果示例
相關(guān)文章
js頁(yè)面加載后執(zhí)行的幾種方式小結(jié)
在實(shí)際應(yīng)用中往往需要在頁(yè)面加載完畢之后再去執(zhí)行相關(guān)的js代碼,之所以這么操作是有道理的,如果是操作dom元素,如果相關(guān)元素沒(méi)有加載完成,而去執(zhí)行js代碼,可能會(huì)導(dǎo)致錯(cuò)誤2020-01-01淺談js對(duì)象屬性 通過(guò)點(diǎn)(.) 和方括號(hào)([]) 的不同之處
下面小編就為大家?guī)?lái)一篇淺談js對(duì)象屬性 通過(guò)點(diǎn)(.) 和方括號(hào)([]) 的不同之處。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10js結(jié)合正則實(shí)現(xiàn)國(guó)內(nèi)手機(jī)號(hào)段校驗(yàn)
這篇文章主要介紹了js結(jié)合正則實(shí)現(xiàn)國(guó)內(nèi)手機(jī)號(hào)段校驗(yàn)的方法以及使用js和jQuery實(shí)現(xiàn)的簡(jiǎn)單校驗(yàn)手機(jī)號(hào)的示例,非常簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。2015-06-06各種頁(yè)面定時(shí)跳轉(zhuǎn)(倒計(jì)時(shí)跳轉(zhuǎn))代碼總結(jié)
下面對(duì)實(shí)現(xiàn)頁(yè)面定時(shí)跳轉(zhuǎn)(也稱倒計(jì)時(shí)跳轉(zhuǎn))做一下總結(jié),以備不時(shí)之需,經(jīng)常使用的朋友可以參考下2013-10-10原生JS實(shí)現(xiàn)DOM加載完成馬上執(zhí)行JS代碼的方法
今天小編就為大家分享一篇原生JS實(shí)現(xiàn)DOM加載完成馬上執(zhí)行JS代碼的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Javascript動(dòng)手實(shí)現(xiàn)call,bind,apply的代碼詳解
這篇文章主要為大家詳細(xì)介紹了Javascript動(dòng)手實(shí)現(xiàn)call,bind,apply的代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02JavaScript計(jì)算字符串實(shí)際長(zhǎng)度方法示例
這篇文章主要為大家介紹了JavaScript計(jì)算字符串實(shí)際長(zhǎng)度方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Typescript 中的 interface 和 type 到底有什么區(qū)別詳解
這篇文章主要介紹了Typescript 中的 interface 和 type 到底有什么區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06