javascript勻速動(dòng)畫和緩沖動(dòng)畫詳解
關(guān)于網(wǎng)頁(yè)中的動(dòng)畫,在css3中我們已經(jīng)可以使用一些屬性快速的做出來(lái),但是有時(shí)候?yàn)榱藶g覽器的兼容性我們還是需要使用js來(lái)制作網(wǎng)頁(yè)中的動(dòng)畫。
使用js做動(dòng)畫最重要的一個(gè)函數(shù)就是setInterval函數(shù),這里不再贅述,不懂可以直接百度用法。本文主要講動(dòng)畫的原理已經(jīng)在制作過(guò)程中的要點(diǎn)。
老規(guī)矩,先上代碼,能直接看懂的可以節(jié)省時(shí)間。
html部分:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>move</title> <link rel="stylesheet" href="move1.css"> </head> <body> <input type="button" value="勻速移動(dòng)" id="move1"> <input type="button" value="漸變移動(dòng)" id="move2"> <div id="box1" class="box"></div> <div id="box2" class="box"></div> <script type="text/javascript" src="move1.js"></script> </body> </html>
css部分:
*{
margin: 0px;
padding: 0px;
}
.box{
width: 100px;
height: 100px;
background-color: green;
position: relative;
margin-top: 10px;
}
js部分:
/**
* Created by siri on 2016/9/10.
*/
window.onload=function () {
var btn1 = document.getElementById('move1');
var btn2 = document.getElementById('move2');
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
btn1.onclick = function () {
animate1(box1,500);
}
btn2.onclick = function () {
animate2(box2,500);
}
//勻速動(dòng)畫
function animate1(ele,target){
//要用定時(shí)器,先清除定時(shí)器
//一個(gè)盒子只能有一個(gè)定時(shí)器,這樣兒的話,不會(huì)和其他盒子出現(xiàn)定時(shí)器沖突
//而定時(shí)器本身講成為盒子的一個(gè)屬性
clearInterval(ele.timer);
//我們要求盒子既能向前又能向后,那么我們的步長(zhǎng)就得有正有負(fù)
//目標(biāo)值如果大于當(dāng)前值取正,目標(biāo)值如果小于當(dāng)前值取負(fù)
var speed = target>ele.offsetLeft?3:-3;
ele.timer = setInterval(function () {
//在執(zhí)行之前就獲取當(dāng)前值和目標(biāo)值之差
var val = target - ele.offsetLeft;
ele.style.left = ele.offsetLeft + speed + "px";
//目標(biāo)值和當(dāng)前值只差如果小于步長(zhǎng),那么就不能再前進(jìn)了
//因?yàn)椴介L(zhǎng)有正有負(fù),所有轉(zhuǎn)換成絕對(duì)值來(lái)比較
console.log(val);
if(Math.abs(val)<=Math.abs(speed)){
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30);
}
//緩動(dòng)動(dòng)畫封裝
function animate2(ele,target) {
clearInterval(ele.timer); //清楚歷史定時(shí)器
ele.timer = setInterval(function () {
//獲取步長(zhǎng) 確定移動(dòng)方向(正負(fù)值) 步長(zhǎng)應(yīng)該是越來(lái)越小的,緩動(dòng)的算法。
var step = (target-ele.offsetLeft)/10;
//對(duì)步長(zhǎng)進(jìn)行二次加工(大于0向上取整,小于0項(xiàng)下取整)
step = step>0?Math.ceil(step):Math.floor(step);
//動(dòng)畫原理: 目標(biāo)位置 = 當(dāng)前位置 + 步長(zhǎng)
console.log(step);
ele.style.left = ele.offsetLeft + step + "px";
//檢測(cè)緩動(dòng)動(dòng)畫有沒(méi)有停止
if(Math.abs(target-ele.offsetLeft)<=Math.abs(step)){
ele.style.left = target + "px"; //直接移動(dòng)指定位置
clearInterval(ele.timer);
}
},30);
}
}
html和css基本就是為了我們的js部分搭框架,不講太多,要注意的是,一定要對(duì)全局的margin和padding清零,否則的話他在計(jì)算的時(shí)候初始的margin和padding會(huì)影響計(jì)算,從而導(dǎo)致有時(shí)候運(yùn)動(dòng)不停止的情況。
javascript部分代碼的解析在源碼中已經(jīng)很詳細(xì)了,下面主要講解原理。
勻速運(yùn)動(dòng):
通過(guò)setInterval函數(shù)我們控制每多少毫秒運(yùn)動(dòng)的距離,然后在快要到達(dá)指定位置的時(shí)候,判斷步長(zhǎng)(每多少毫秒運(yùn)動(dòng)的距離)和此時(shí)和目標(biāo)位置的距離,如果步長(zhǎng)大于此時(shí)和目標(biāo)位置的距離,則直接定位到目標(biāo)位置,這樣做是為了避免步長(zhǎng)和總距離不是整數(shù)倍關(guān)系而產(chǎn)生最后到達(dá)位置和目標(biāo)位置有差值的錯(cuò)誤。
緩沖運(yùn)動(dòng):
緩沖運(yùn)動(dòng)的基本函數(shù)是和勻速運(yùn)動(dòng)一樣的,只是緩沖運(yùn)動(dòng)的步長(zhǎng)我們是通過(guò)和目標(biāo)位置的距離來(lái)確定的,這樣我們的步長(zhǎng)是不斷變小的,從而實(shí)現(xiàn)緩沖運(yùn)動(dòng)的效果。在確定步長(zhǎng)的時(shí)候我們使用Math.ceil和Math.floor對(duì)步長(zhǎng)值進(jìn)行取整是為了避免出現(xiàn)小數(shù),因?yàn)槿绻霈F(xiàn)小數(shù)后面最后到達(dá)的位置肯定是和目標(biāo)位置有誤差的。
注意事項(xiàng):在每次移動(dòng)開(kāi)始前一定要使用clearInterval清除定時(shí)器。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript DOM 編程藝術(shù)(第2版)讀書(shū)筆記(JavaScript的最佳實(shí)踐)
閱讀了本書(shū)第五章關(guān)于使用JavaScript的最佳實(shí)踐,大部分的建議之前都有耳聞,不過(guò)閱讀之后有更深的體會(huì)2013-10-10
非主流的textarea自增長(zhǎng)實(shí)現(xiàn)js代碼
今天稍微研究了下textarea隨輸入內(nèi)容自動(dòng)增長(zhǎng)的功能,通過(guò)google參考了一些實(shí)現(xiàn)方式2011-12-12
Bootstrap 響應(yīng)式實(shí)用工具實(shí)例詳解
Bootstrap 提供了一些輔助類,以便更快地實(shí)現(xiàn)對(duì)移動(dòng)設(shè)備友好的開(kāi)發(fā)。這些可以通過(guò)媒體查詢結(jié)合大型、小型和中型設(shè)備,實(shí)現(xiàn)內(nèi)容對(duì)設(shè)備的顯示和隱藏。下面通過(guò)本文給大家分享Bootstrap 響應(yīng)式實(shí)用工具,一起看看吧2017-03-03
JS中錨點(diǎn)鏈接點(diǎn)擊平滑滾動(dòng)并自由調(diào)整到頂部位置
這篇文章主要介紹了JS中錨點(diǎn)鏈接點(diǎn)擊平滑滾動(dòng)并自由調(diào)整到頂部位置,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
JavaScript設(shè)置表單上傳時(shí)文件個(gè)數(shù)的方法
這篇文章主要介紹了JavaScript設(shè)置表單上傳時(shí)文件個(gè)數(shù)的方法,可實(shí)現(xiàn)動(dòng)態(tài)增加及刪除表單上傳按鈕的功能,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08
6種JavaScript判斷對(duì)象自身為空的方法小結(jié)
這篇文章主要為大家詳細(xì)介紹了6種JavaScript判斷對(duì)象自身為空的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12
IE Firefox 使用自定義標(biāo)簽的區(qū)別
IE Firefox 使用自定義標(biāo)簽的區(qū)別,需要的朋友可以參考下。2009-10-10
JS操作xml對(duì)象轉(zhuǎn)換為Json對(duì)象示例
本篇文章主要介紹了JS操作xml對(duì)象轉(zhuǎn)換為Json對(duì)象示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03

