JavaScript動畫函式封裝詳解
目錄
- 一、動畫函式原理
- 二、動畫函式簡單封裝
- 三、 動畫函式給不同元素記錄不同定時器
- 四、緩動效果原理
- 五、 動畫函式在多個目標值之間移動
- 六、動畫函式添加回調函式
一、動畫函式原理
核心原理:通過定時器setInterval() 不斷移動盒子位置。
實現步驟:
- 獲得盒子當前位置
- 讓盒子在當前位置加上1個移動距離
- 利用定時器不斷重複這個操作
- 加一個結束定時器的條件
- 注意此元素需要新增定位,才能使用element.style.left
如下所示:
給定一個盒子,讓其慢慢移動到300px的位置。
程式碼如下:
<style> div{ position: absolute; left: 0; top: 0; width: 100px; height: 100px; background-color: cyan; } </style> </head> <body> <div></div> <script> var div = document.querySelector('div'); var timer = setInterval(function(){ if(div.offsetLeft >= 300){ clearInterval(timer); } div.style.left = div.offsetLeft + 1 +'px'; },30); </script> </body>
執行結果為:
執行成功。
但是如果同時有好幾個元素都需要新增動畫呢?我們就可以考慮將其封裝成一個簡單的動畫函式。
二、動畫www.cppcns.com函式簡單封裝
函式需要傳遞2個引數,動畫物件和移動到的距離。如下所示:
function animate(obj,target){ var timer = setInterval(function(){ if(obj.offsetLeft >= target){ clearInterval(timer); } obj.style.left = obj.offsetLeft + 1 +'px'; },30); }
我們就可以通過呼叫上述封裝的函式來實現動畫效果。例如,給定兩個不同的盒子,分別呼叫動畫函式:
<style> .box1{ position: absolute; left: 0; top: 50px; width: 100px; height: 100px; background-color: cyan; } .box2{ position: absolute; left: 0; top: 155px; width: 150px; height: 150px; background-color: deepskyblue; } </style> <body> <div class="box1"></div> <div class="box2"></div> <script> function animate(obj,30); } var box1 = document.querySelector(xiQDpcMEj'.box1'); var box2 = document.querySelector('.box2'); animate(box1,300); animate(box2,400); </script> </body>
效果為:
成功實現了動畫的效果。
但是上面封裝的動畫函式還是有問題的,每當我們呼叫一次動畫函式,就會給我們開闢一塊記憶體空間,會造成浪費記憶體資源的問題,而且我們每次呼叫的動畫函式都是以同一個名字命名的,很容易引起歧義,所以我們就可以給不同的元素使用不同的定時器(自己專門用自己的定時器)。
三、 動畫函式給不同元素記錄不同定時器
核心原理:利用 是一門動態語言,可以很方便的給當前物件新增屬性。
通過給物件新增屬性的方法給給不同的元素新增定時器,我們可以將其進行如下的封裝:
function animate(obj,target){ obj.timer = setInterval(function(){ if(obj.offsetLeft >= target){ clearInterval(obj.timer); } obj.style.left = obj.offsetLeft + 1 +'px'; },30); }
當然,如果我們想要讓某個元素在我們進行一系列操作後才實現動畫效果的話,我們就可以給其新增特定事件,然後將函式呼叫寫在事件中,
以第一個例子為例,給它新增點選事件,當點選按鈕後,才讓這個盒子發生移動:
var box1 = document.querySelector('.box1'); var btn = document.querySelector('button') btn.addEventListener('click',function(){ animate(box1,300); })
效果為:
效果實現,但是如果我們一直點選按鈕,會出現什麼情況呢?
我們會發現,當我們不斷點選按鈕時,盒子執行的速度會越來越快,這是因為我們同時開啟了太多定時器。該如何解決呢?方案就是讓我們的元素先清除以前的定時器,只保留一個定時器執行,所以,我們就可以在函式的最上面新增一個清除定時器的操作。程式碼為:
function animate(obj,target){ clearInterval(obj.timer); obj.timer = setInterval(function(){ if(obj.offsetLeft >= target){ clearInterval(obj.timer); } obj.style.left = obj.offsetLeft + 1 +'px'; },30); } var box1 = document.querySelector('.box1'); var btn = document.querySelector('button'); btn.addEventListener('click',300); })
此時的執行效果為
成功實現。
通過上述一系列操作,我們可以發現,我們所實現的動xiQDpcMEj畫都是勻速的,為了讓效果更加好看,我們可以讓我們的動畫以緩動的速度執行。
四、緩動效果原理
緩動動畫就是讓元素運動速度有所變化,最常見的是讓速度慢慢停下來。
- 思路:讓盒子每次移動的距離慢慢變小,速度就會慢慢落下來。
- 核心演算法: (目標值 - 現在的位置 ) / 10 做為每次移動的距離 步長
- 停止的條件: 讓當前盒子位置等於目標位置就停止定時器
注意步長值需要取整
以上個例子為例,當我們點選按鈕時,讓元素以緩動的速度移動,我們可以將封裝的動畫函式改為:
function animate(obj,target){
clearInterval(obj.timer)
obj.timer = setIntervalwww.cppcns.com(function(){
var step = (target - obj.offsetLeft)/10;
if(obj.offsetLeft == target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step +'px';
},30);
}
實現效果為:
這樣的效果是不是更好看了呢?但是我們來檢查一下我們的元素具體移動了多大距離,是不是剛好到目標值300px的位置呢?
通過檢查我們發現,我們的元素並沒有到指定位置,這是因為我們的步長公式是有問題的,進行除法運算時,可能會有小數,從而導致位置的偏差,所以我們就需要對步長公式進行取整操作,由於元素是向前運動(正方向),所以我們採用的策略是向上取整:
var step = Math.ceil((target - obj.offsetLeft)/10);
此時我們在來看看最終到達的目標位置是:
此時就剛好到達了目標位置。
五、 動畫函式在多個目標值之間移動
但是如果我們的步長為負呢?
舉個例子,現在有一個盒子,給其新增兩個按鈕,一個讓元素移動到400px的位置,一個讓元素移動到700px:
function animate(obj,target){ clearInterval(obj.timer) obj.timer = setInterval(function(){ var step = Math.ceil((target - obj.offsetLeft)/10); if(obj.offsetLeft >= target){ clearInterval(obj.timer); } obj.style.left = obj.offsetLeft + step +'px'; },30); } var box1 = document.querySelector('.box1'); var btn = document.querySelectorAll('button') btn[0].addEventListener('click',function(){ animate(box1,400); }) btn[1].addEventListener('click',700); })
實現效果為:
此時發現,當我們正向運動的時候,元素可以精確的到達目標位置,且元素也能實現在兩個畫素間移動的效果,但是向後退時達到的位置卻並不是目標位置,這是因為我們的元素在倒退的時候,是屬於反向運動的,這時我們也應該讓步長向反向長的位置取整,即向下取整。
這時,我們應該對步長條件進行判斷,如果步長大於零,則向上取整,如果步長小於零,則向下取整,調整後的步長公式為:
var step =(target - obj.offsetLeft)/10; step > 0 ? Math.ceil(step) : Math.floor(step);
此時再來看看效果:
問題就解決了。
但是我們此時只是簡單的實現了一個元素在兩個位置的移動,如果我們想要在它移動後改變顏色,該如何操作呢?我們就可以通過給動畫函式添加回調函式 來實現。
六、動畫函式添加回調函式
回撥函式原理:函式可以作為一個引數。將這個函式作為引數傳到另一個函式裡面,當那個函式執行完之後,再執行傳進去的這個函式,這個過程就叫做回撥。
回撥函式寫的位置:定時器結束的位置。
具體實現程式碼為:
function animate(obj,target,callback){ clearInterval(obj.timer) obj.timer = setInterval(function(){ var step =(target - obj.offsetLeft)/10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if(obj.offsetLeft == target){ clearInterval(obj.timer); if(callback){ callback(); } } obj.style.left = obj.offsetLeft + step +'px'; },30); } var box1 = document.querySelector('.box1'); var btn = document.querySelectorAll('button'); btn[0].addEventListener('click',function(){ www.cppcns.com animate(box1,400,function(){ box1.style.backgroundColor = 'pink'; }); }) btn[1].addEventListener('click',700,function(){ box1.style.backgroundColor = 'red'; }); })
實現效果為:
以上就是動畫函式的封裝,在具體使用的時候,我們就可以將其封裝成一個js檔案,需要的時候就可以直接引用。
到此這篇關於動畫函式封裝詳解的文章就介紹到這了,更多相關Script動畫函式封裝內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!