JavaScript動畫函數(shù)封裝詳解
一、動畫函數(shù)原理
核心原理:通過定時器setInterval() 不斷移動盒子位置。
實現(xiàn)步驟:
- 獲得盒子當前位置
- 讓盒子在當前位置加上1個移動距離
- 利用定時器不斷重復(fù)這個操作
- 加一個結(jié)束定時器的條件
- 注意此元素需要添加定位,才能使用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>
運行結(jié)果為:

運行成功。
但是如果同時有好幾個元素都需要添加動畫呢?我們就可以考慮將其封裝成一個簡單的動畫函數(shù)。
二、動畫函數(shù)簡單封裝
函數(shù)需要傳遞2個參數(shù),動畫對象和移動到的距離。如下所示:
function animate(obj,target){
var timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 +'px';
},30);
}
我們就可以通過調(diào)用上述封裝的函數(shù)來實現(xiàn)動畫效果。例如,給定兩個不同的盒子,分別調(diào)用動畫函數(shù):
<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,target){
var timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 +'px';
},30);
}
var box1 = document.querySelector('.box1');
var box2 = document.querySelector('.box2');
animate(box1,300);
animate(box2,400);
</script>
</body>
效果為:

成功實現(xiàn)了動畫的效果。
但是上面封裝的動畫函數(shù)還是有問題的,每當我們調(diào)用一次動畫函數(shù),就會給我們開辟一塊內(nèi)存空間,會造成浪費內(nèi)存資源的問題,而且我們每次調(diào)用的動畫函數(shù)都是以同一個名字命名的,很容易引起歧義,所以我們就可以給不同的元素使用不同的定時器(自己專門用自己的定時器)。
三、 動畫函數(shù)給不同元素記錄不同定時器
核心原理:利用 JS 是一門動態(tài)語言,可以很方便的給當前對象添加屬性。
通過給對象添加屬性的方法給給不同的元素添加定時器,我們可以將其進行如下的封裝:
function animate(obj,target){
obj.timer = setInterval(function(){
if(obj.offsetLeft >= target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 +'px';
},30);
}
當然,如果我們想要讓某個元素在我們進行一系列操作后才實現(xiàn)動畫效果的話,我們就可以給其添加特定事件,然后將函數(shù)調(diào)用寫在事件中,
以第一個例子為例,給它添加點擊事件,當點擊按鈕后,才讓這個盒子發(fā)生移動:
var box1 = document.querySelector('.box1');
var btn = document.querySelector('button')
btn.addEventListener('click',function(){
animate(box1,300);
})
效果為:

效果實現(xiàn),但是如果我們一直點擊按鈕,會出現(xiàn)什么情況呢?

我們會發(fā)現(xiàn),當我們不斷點擊按鈕時,盒子運行的速度會越來越快,這是因為我們同時開啟了太多定時器。該如何解決呢?方案就是讓我們的元素先清除以前的定時器,只保留一個定時器執(zhí)行,所以,我們就可以在函數(shù)的最上面添加一個清除定時器的操作。代碼為:
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',function(){
animate(box1,300);
})
此時的運行效果為
成功實現(xiàn)。
通過上述一系列操作,我們可以發(fā)現(xiàn),我們所實現(xiàn)的動畫都是勻速的,為了讓效果更加好看,我們可以讓我們的動畫以緩動的速度運行。

四、緩動效果原理
緩動動畫就是讓元素運動速度有所變化,最常見的是讓速度慢慢停下來。
- 思路:讓盒子每次移動的距離慢慢變小,速度就會慢慢落下來。
- 核心算法: (目標值 - 現(xiàn)在的位置 ) / 10 做為每次移動的距離 步長
- 停止的條件: 讓當前盒子位置等于目標位置就停止定時器
注意步長值需要取整
以上個例子為例,當我們點擊按鈕時,讓元素以緩動的速度移動,我們可以將封裝的動畫函數(shù)改為:
function animate(obj,target){
clearInterval(obj.timer)
obj.timer = setInterval(function(){
var step = (target - obj.offsetLeft)/10;
if(obj.offsetLeft == target){
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + step +'px';
},30);
}
實現(xiàn)效果為:

這樣的效果是不是更好看了呢?但是我們來檢查一下我們的元素具體移動了多大距離,是不是剛好到目標值300px的位置呢?

通過檢查我們發(fā)現(xiàn),我們的元素并沒有到指定位置,這是因為我們的步長公式是有問題的,進行除法運算時,可能會有小數(shù),從而導(dǎo)致位置的偏差,所以我們就需要對步長公式進行取整操作,由于元素是向前運動(正方向),所以我們采用的策略是向上取整:
var step = Math.ceil((target - obj.offsetLeft)/10);
此時我們在來看看最終到達的目標位置是:

此時就剛好到達了目標位置。
五、 動畫函數(shù)在多個目標值之間移動
但是如果我們的步長為負呢?
舉個例子,現(xiàn)在有一個盒子,給其添加兩個按鈕,一個讓元素移動到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',function(){
animate(box1,700);
})
實現(xiàn)效果為:

此時發(fā)現(xiàn),當我們正向運動的時候,元素可以精確的到達目標位置,且元素也能實現(xiàn)在兩個像素間移動的效果,但是向后退時達到的位置卻并不是目標位置,這是因為我們的元素在倒退的時候,是屬于反向運動的,這時我們也應(yīng)該讓步長向反向長的位置取整,即向下取整。
這時,我們應(yīng)該對步長條件進行判斷,如果步長大于零,則向上取整,如果步長小于零,則向下取整,調(diào)整后的步長公式為:
var step =(target - obj.offsetLeft)/10; step > 0 ? Math.ceil(step) : Math.floor(step);
此時再來看看效果:

問題就解決了。
但是我們此時只是簡單的實現(xiàn)了一個元素在兩個位置的移動,如果我們想要在它移動后改變顏色,該如何操作呢?我們就可以通過給動畫函數(shù)添加回調(diào)函數(shù) 來實現(xiàn)。
六、動畫函數(shù)添加回調(diào)函數(shù)
回調(diào)函數(shù)原理:函數(shù)可以作為一個參數(shù)。將這個函數(shù)作為參數(shù)傳到另一個函數(shù)里面,當那個函數(shù)執(zhí)行完之后,再執(zhí)行傳進去的這個函數(shù),這個過程就叫做回調(diào)。
回調(diào)函數(shù)寫的位置:定時器結(jié)束的位置。
具體實現(xiàn)代碼為:
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(){
animate(box1,400,function(){
box1.style.backgroundColor = 'pink';
});
})
btn[1].addEventListener('click',function(){
animate(box1,700,function(){
box1.style.backgroundColor = 'red';
});
})
實現(xiàn)效果為:

以上就是動畫函數(shù)的封裝,在具體使用的時候,我們就可以將其封裝成一個js文件,需要的時候就可以直接引用。
?到此這篇關(guān)于JavaScript動畫函數(shù)封裝詳解的文章就介紹到這了,更多相關(guān)JavaScript動畫函數(shù)封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript使用百度地圖api和html5特性獲取瀏覽器位置
本文介紹了javascript使用百度地圖api和html5特性獲取瀏覽器位置的小功能,大家參考使用吧2014-01-01
使用百度地圖api實現(xiàn)根據(jù)地址查詢經(jīng)緯度
這篇文章主要介紹了使用百度地圖api實現(xiàn)根據(jù)地址查詢經(jīng)緯度的方法,附上實例,推薦給有需要的小伙伴們。2014-12-12
WordPress 單頁面上一頁下一頁的實現(xiàn)方法【附代碼】
下面小編就為大家?guī)硪黄猈ordPress 單頁面上一頁下一頁的實現(xiàn)方法【附代碼】。小編覺得非常不錯。給大家分享一下。希望能給大家一個參考。2016-03-03
JS基于構(gòu)造函數(shù)實現(xiàn)的菜單滑動顯隱效果【測試可用】
這篇文章主要介紹了JS基于構(gòu)造函數(shù)實現(xiàn)的菜單滑動顯隱效果,可實現(xiàn)基本的菜單折疊與展開功能,涉及javascript響應(yīng)鼠標事件動態(tài)操作頁面元素的相關(guān)技巧,需要的朋友可以參考下2016-06-06

