Javascript動畫效果(1)
前面我們介紹了Javascript的回到頂部效果,今天呢,我們對Javascript動畫做進一步的研究。在這篇博文中我們只介紹簡單的勻速運動、簡單的緩沖運動和簡單的多物體運動后面我們還會介紹任意值變化的運動、鏈式運動、同時運動,同時我們還會簡單的封裝一個運動插件并且還會將Javascript方法和jquery方法進行比較。
1、簡單的勻速運動
下面我們介紹一個demo,鼠標(biāo)移入,動畫向右移動(即隱藏部分顯示);鼠標(biāo)離開,動畫向左運動(繼續(xù)隱藏)整個過程都是勻速的。有了前面回到頂部效果作為基礎(chǔ),這里主要講解重要部分,先來看看代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>demo1</title> <style type="text/css"> body,div,span{ margin: 0px; padding: 0px; } #div1{ width: 200px; height: 200px; background: red; position: relative; left: -200px; } #share{ width: 20px; height: 40px; background: blue; position: absolute; left: 200px; top: 75px; } </style> <script type="text/javascript"> //一進來就加載 window.onload = function(){ //獲取div var oDiv = document.getElementById('div1'); //鼠標(biāo)移入時執(zhí)行函數(shù) oDiv.onmouseover = function(){ startMove(); } //鼠標(biāo)移出時執(zhí)行函數(shù) oDiv.onmouseout = function(){ startMove1(); } } //定義一個定時器 var timer = null; function startMove(){ //讓它一進來的時候就把計時器清掉,避免后面引入多個計時器 clearInterval(timer); var oDiv = document.getElementById('div1'); //插入一個定時器 timer = setInterval(function(){ // oDiv.style.left = oDiv.offsetLeft+10+'px'; // //offsetLeft 當(dāng)前l(fā)eft的值 // //此時運行的結(jié)果為鼠標(biāo)移上去后,一直在動,此時需要if進行判斷 if(oDiv.offsetLeft == 0){ //當(dāng)當(dāng)前的left值為0的時候,清空計時器 clearInterval(timer); } else{ //當(dāng)當(dāng)前的left值不為0的時候,進行移動 oDiv.style.left = oDiv.offsetLeft+10+'px'; } },30) } function startMove1(){ clearInterval(timer); var oDiv = document.getElementById('div1'); timer = setInterval(function(){ if(oDiv.offsetLeft == -200){ clearInterval(timer); } else{ oDiv.style.left = oDiv.offsetLeft-10+'px'; } },30) } //可以修改當(dāng)前內(nèi)容里面相同的部分 </script> </head> <body> <div id="div1"> <span id="share"> 分享 </span> </div> </body> </html>
在Javascript部分,我們發(fā)現(xiàn)有很多代碼重復(fù)了,這時我們可以通過將不同的地方用參數(shù)的方法傳進去,主要代碼如下:
/* * 前面的onmouseover和onmouseout事件中分別改為 * startMove(10,0); * startMove(-10,-200); * 后面再將 startMove和startMove1兩個函數(shù)進行合并,代碼如下: */ function startMove(speed,iTarget){ clearInterval(timer); var oDiv = document.getElementById('div1'); timer = setInterval(function(){ if(oDiv.offsetLeft == iTarget){ clearInterval(timer); } else{ oDiv.style.left = oDiv.offsetLeft+speed+'px'; } },30) }
此時我們還是會發(fā)現(xiàn)一個問題,就是,在功能相同的情況下,參數(shù)越少越好,這時我們要對我們之前的代碼做進一步修改,因為iTarget是目標(biāo)值,所以我們考慮將speed參數(shù)去掉,代碼如下:
//考慮參數(shù)越少越好原則,可以去掉speed,同時,前面的onmouseover和onmouseout事件也應(yīng)相應(yīng)改變 function startMove(iTarget){ clearInterval(timer); var oDiv = document.getElementById('div1'); timer = setInterval(function(){ //定義一個speed var speed = 0; //對speed進行判斷 if(oDiv.offsetLeft > iTarget){ //當(dāng)oDiv.offsetLeft > iTarget時,應(yīng)該向左移動 speed = -10; } else{ speed = 10; } if(oDiv.offsetLeft == iTarget){ clearInterval(timer); } else{ oDiv.style.left = oDiv.offsetLeft+speed+'px'; } },30) }
到這里,我們的勻速運動效果基本完成。在上面的demo中,我們改變的是left效果,同理我們還可以改變right,width和height效果。思考:在css3動畫中有改變透明度的效果,在這里我們是否可以通過前面的方式來得到實現(xiàn)呢?
答案:大致可以用上面的方法去實現(xiàn),但是有個小小的問題值得注意,無論是left,right還是width,height它們都有單位px(在上面的demo中,有一行代碼就是這樣:oDiv.style.left = oDiv.offsetLeft+speed+'px';),而透明度無論是opacity也好,是filter也好,它們都是沒有單位的,故我們可以寫如下代碼:
alpha += speed; oDiv.style.filter = 'alpha(opacity:'+alpha+')'; oDiv.style.opacity = alpha/100;
完整代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>demo2</title> <style type="text/css"> body,div{ margin: 0px; padding: 0px; } #div1{ width: 200px; height: 200px; background: red; filter: alpha(opacity:30); opacity: 0.3; } </style> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementById('div1'); oDiv.onmouseover = function(){ startMove(100); //鼠標(biāo)移入的時候,透明度為100% } oDiv.onmouseout = function(){ startMove(30); //鼠標(biāo)移出的時候,透明度為30% } } var timer = null; var alpha = 30; function startMove(iTarget){ var oDiv = document.getElementById('div1'); clearInterval(timer); //在運行之前,先關(guān)閉定時器 //關(guān)了定時器后,現(xiàn)在運行時需要加定時器 timer = setInterval(function(){ var speed = 0; if(alpha > iTarget){ speed = -10; } else{ speed = 10 } if(alpha == iTarget){ clearInterval(timer); } else{ alpha += speed; oDiv.style.filter = 'alpha(opacity:'+alpha+')'; oDiv.style.opacity = alpha/100; } },30) } </script> </head> <body> <div id="div1"> 要求: <p>鼠標(biāo)移入,透明度為100%;鼠標(biāo)移出,透明度為30%</p> </div> </body> </html>
到這里,我們的速度動畫就告一段落了。關(guān)于opacity和filter,詳情請見這里
2、緩沖運動
回憶之前回到頂部效果,為了增加用戶的體驗效果,回到頂部時是先快后慢。有了前面的基礎(chǔ),這里句很好辦了,以demo1為例,我們可以添加如下代碼:
function startMove(iTarget){ var oDiv = document.getElementById('div1'); clearInterval(timer); timer = setInterval(function(){ var speed = (iTarget - oDiv.offsetLeft)/20; speed = speed>0?Math.ceil(speed):Math.floor(speed); //注意這里的取整問題,不然運動后回不到原來的位置 // if(speed > 0){ // speed = Math.ceil(speed); // } // else{ // speed = Math.floor(speed); // } if(iTarget == oDiv.offsetLeft){ clearInterval(timer); } else{ oDiv.style.left = oDiv.offsetLeft+speed+'px'; } },30) }
在這段代碼中,var speed = (iTarget - oDiv.offsetLeft)/20;通過控制被除數(shù)可以控制動畫的速度,然后我們分別用Math.floor和Math.ceil分別進行向下和向上取整,如果沒用取整,那么鼠標(biāo)移入和移出都達不到想要的效果(計算機在進行計算時總是有誤差的)。到這里,緩沖運動也介紹的差不多了。下面我們來介紹多物體運動。
3、多物體運動
有了前面的基礎(chǔ),我們來看多物體運動時就覺得簡單了。在多物體運動中,我們將寬度變化和透明度變化分開來講
【多物體寬度變化】
在多物體寬度變化中,我們用無序列表來實現(xiàn)。與單個物體寬度變化不同的是,我們要用for循環(huán)依次遍歷我們想要的值,關(guān)鍵代碼如下:
var aLi = document.getElementsByTagName('li'); for(var i = 0; i< aLi.length; i++){ //i=0 aLi[i].onmouseover = function(){ startMove(this,400); } aLi[i].onmouseout = function(){ startMove(this,200); } }
全代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>多物體動畫</title> <style type="text/css"> body,ul,li{ margin: 0px; padding: 0px; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; } </style> <script type="text/javascript"> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for(var i = 0; i< aLi.length; i++){ //i=0 aLi[i].timer = null; aLi[i].onmouseover = function(){ startMove(this,400);//this指向當(dāng)前的aLi[i].onmouseover事件 } aLi[i].onmouseout = function(){ startMove(this,200);//this指向當(dāng)前的aLi[i].onmouseout事件 } } } //var timer = null; /* * 若該代碼還是在這里,當(dāng)鼠標(biāo)依次緩慢經(jīng)過時不會出現(xiàn)大的問題,但是當(dāng)移動的速度比較快時,會發(fā)現(xiàn)有問題:可以變得越來越寬 * 原因:timer并不是每次在鼠標(biāo)經(jīng)過每一個區(qū)域時為null * 解決辦法:在前面的for循環(huán)中加上aLi[i].timer = null;這樣每次執(zhí)行前都是null開始 */ function startMove(obj,iTarget){//因為li有多個,這里需要再傳一個參數(shù)obj //var aLi = document.getElementsByTagName('li'); clearInterval(obj.timer); obj.timer = setInterval(function(){ var speed = (iTarget - obj.offsetWidth)/10; speed = speed>0?Math.ceil(speed):Math.floor(speed); if(iTarget == obj.offsetWidth){ clearInterval(obj.timer); } else{ obj.style.width = obj.offsetWidth+speed+'px'; //是obj 不是 aLi } },30) } </script> </head> <body> <ul> <li></li> <li></li> <li></li> </ul> </body> </html>
【多物體透明度動畫】
有了上面的例子,我們就能很容易的寫出多物體透明度動畫的代碼,代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>多物體透明度動畫</title> <style type="text/css"> body,div{ margin: 0px; padding: 0px; } div{ width: 200px; height: 200px; background: red; margin: 10px; float: left; filter:alpha(opacity:30); opacity:0.3; } </style> <script type="text/javascript"> window.onload = function(){ var oDiv = document.getElementsByTagName('div'); for(var i=0;i<oDiv.length;i++){ oDiv[i].timer = null; oDiv[i].alpha = 30; oDiv[i].onmouseover = function(){ startMove(this,100); } oDiv[i].onmouseout = function(){ startMove(this,30); } } } //var alpha = 30; function startMove(obj,iTarget){ clearInterval(obj.timer); obj.timer = setInterval(function(){ var speed = 0; if(iTarget > obj.alpha){ speed = 10; } else{ speed = -10; } if(iTarget == obj.alpha){ clearInterval(obj.timer); } else{ obj.alpha +=speed; obj.style.filter = 'obj.alpha(opacity:'+obj.alpha+')'; obj.style.opacity = obj.alpha/100; } },30) } </script> </head> <body> <div id="div1"></div> <div id="div2"></div> <div id="div3"></div> <div id="div4"></div> </body> </html>
和之前的timer一樣,alpha = 30;也需要寫在for循環(huán)的后面。
到這里,簡單的動畫效果就告一段落了,慢慢的一步一步的去修改去嘗試就會有新的發(fā)現(xiàn)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript/TypeScript中==和===的區(qū)別詳解
這篇文章主要給大家介紹了關(guān)于JavaScript/TypeScript中==和===區(qū)別的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-03-03一文掌握JavaScript數(shù)組常用工具函數(shù)總結(jié)
這篇文章主要介紹了一文掌握JavaScript數(shù)組常用工具函數(shù)總結(jié),文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值2022-06-06layui使用及簡單的三級聯(lián)動實現(xiàn)教程
這篇文章主要給大家介紹了關(guān)于layui使用及簡單的三級聯(lián)動的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12JavaScript 刪除或抽取字符串指定字符的方法(極為常用)
這篇文章主要給大家分享了極為常用的JavaScript 刪除或抽取字符串指定字符的所有方法,具有一定的參考價值,需要的小伙伴可以參考一下2021-12-12跟我學(xué)習(xí)javascript的隱式強制轉(zhuǎn)換
跟我學(xué)習(xí)javascript的隱式強制轉(zhuǎn)換,感興趣的小伙伴們可以學(xué)習(xí)一下2015-11-11基于JavaScript或jQuery實現(xiàn)網(wǎng)站夜間/高亮模式
這篇文章主要介紹了基于JavaScript或jQuery實現(xiàn)網(wǎng)站夜間/高亮模式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05