js很強大 相信很多人都知道,那么它有哪些強大之處呢?有興趣的人可以去查查,這里就不贅述了,因為不在本片文章討論的范圍。
我們要講的是怎么用原生JS寫移動動畫?我們先舉一個最簡單的動畫例子,很多網站的左邊或右邊會有個分享的框,鼠標放上去就還移出一個列表,里面是要分享的地址。鼠標移開,就會移進去。
要實現這個效果要怎么做呢?
可以想一想,鼠標經過和鼠標離開很好理解 用onmousemove事件和onmouseout事件就能完成。
那移動動畫呢?我們可以一步一步思考,
首先,一開始是這樣的
完成移動完成后是這樣的(只是案例 里面的內容可以自己隨便寫)
那么怎么樣做到一開始的樣子呢?我們先用絕對定位,然后對left值寫負數。這樣就完成了初始。
position: absolute; left: -200px; top: 0px;
然后怎么讓他移動呢?在Flash中的動畫是由幀組成的,每幀移動一點就組成一幅完整連續的動畫。
同理,我們知道在JS中有 setInterval 它是每隔多少秒執行一次函數。setInterval (a,2000);每個2秒執行一次a函數。
然后我們每隔40毫秒向右移動10像素。這樣看起來就是連續不斷的移動了。
window.onload=function(){ var left_yd =document.getElementById("left_yidong"); left_yd.onmousemove=function(){ //鼠標經過事件 donghua(0,10,40); //(lefts為多少像素時停止,40為每40毫秒執行一次,10為每次移動10像素,控制速度)注意此處lefts的值為0 } left_yd.onmouseout=function(){ //鼠標離開事件 donghua(-200,-10,40);//注意此處lefts的值為left_yidong盒子的left的值。此處為-200px } }; //以下函數請勿隨意改動,以免出現錯誤。 var times=null; function donghua(lefts,speen,time){ //(lefts為多少像素時停止,每隔time毫秒執行一次用了控制速度) clearInterval(times);//停止times var left_yd =document.getElementById("left_yidong"); times=setInterval(function(){ if(left_yd.offsetLeft==lefts) { clearInterval(times); }else { left_yd.style.left=left_yd.offsetLeft+speen+'px'; } },time); }
這樣的話動畫就完成了,注意id名稱改為自己的。
但是這樣的動畫是勻速的,我個人不是很喜歡,我想做一個運動速度越來越慢的動畫怎么做?
很簡單嘛,就是每次移動的像素的值減小 就是上面代碼的speen的值
1 window.onload=function(){ 2 var left_yd =document.getElementById("left_yidong"); 3 left_yd.onmousemove=function(){ //鼠標經過事件 4 donghua(0,40); //(lefts為多少像素時停止,40為每40毫秒執行一次,控制速度)注意此處lefts的值為0 5 } 6 left_yd.onmouseout=function(){ //鼠標離開事件 7 donghua(-200,40);//注意此處lefts的值為left_yidong盒子的left的值。此處為-200px 8 } 9 }; 10 //以下函數請勿隨意改動,以免出現錯誤。 11 var times=null; 12 function donghua(lefts,time){ //(lefts為多少像素時停止,每隔time毫秒執行一次用了控制速度) 13 clearInterval(times); 14 var left_yd =document.getElementById("left_yidong"); 15 times=setInterval(function(){ 16 var speen=(lefts-left_yd.offsetLeft)/20; //目標值減去當前值再除20,控制速度先快后慢 17 speen=speen>0?Math.ceil(speen):Math.floor(speen);//speen的判斷並向上或向下取整 18 if(left_yd.offsetLeft==lefts) 19 { 20 clearInterval(times); 21 }else { 22 left_yd.style.left=left_yd.offsetLeft+speen+'px'; 23 } 24 },time); 25 }
新加入第16,17行代碼就完成了,第16行是用來改變speen的值的,而第17行是用來取整的 不然會出現小數,從而出現位置不正確的錯誤。
以一下是全部代碼:(樣式不好看,別介意)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 #left_yidong{ 8 width: 200px; 9 height: 500px; 10 background-color:#a6e1ec; 11 border-radius: 5px; 12 position: absolute; 13 left: -200px; 14 top: 0px; 15 } 16 #left_function{ 17 width: 30px; 18 height: 50px; 19 background-color: #46b8da; 20 border-radius: 2px; 21 text-align: center; 22 line-height: 25px; 23 position: absolute; 24 left: 200px; 25 top: 200px; 26 } 27 </style> 28 <script> 29 window.onload=function(){ 30 var left_yd =document.getElementById("left_yidong"); 31 left_yd.onmousemove=function(){ //鼠標經過事件 32 donghua(0,40); //(lefts為多少像素時停止,40為每40毫秒執行一次,控制速度)注意此處lefts的值為0 33 } 34 left_yd.onmouseout=function(){ //鼠標離開事件 35 donghua(-200,40);//注意此處lefts的值為left_yidong盒子的left的值。此處為-200px 36 } 37 }; 38 //以下函數請勿隨意改動,以免出現錯誤。 39 var times=null; 40 function donghua(lefts,time){ //(lefts為多少像素時停止,每隔time毫秒執行一次用了控制速度) 41 clearInterval(times); 42 var left_yd =document.getElementById("left_yidong"); 43 times=setInterval(function(){ 44 var speen=(lefts-left_yd.offsetLeft)/20;//目標值減去當前值再除20,控制速度先快后慢 45 speen=speen>0?Math.ceil(speen):Math.floor(speen);//speen的判斷並向上或向下取整 46 if(left_yd.offsetLeft==lefts) 47 { 48 clearInterval(times); 49 }else { 50 left_yd.style.left=left_yd.offsetLeft+speen+'px'; 51 } 52 },time); 53 } 54 </script> 55 </head> 56 <body> 57 <div id="left_yidong"> 58 <p>在這里插入你想要的內容</p> 59 <p>在這里插入你想要的內容</p> 60 <p>在這里插入你想要的內容</p> 61 <p>在這里插入你想要的內容</p> 62 <p>在這里插入你想要的內容</p> 63 <div id="left_function">分享</div> 64 </div> 65 </body> 66 </html>
實際應用:
下面我們將上面的技術運用到實際案例中:
一開始登錄框在整個頁面最上面,打開界面后登錄框慢慢向下移除。就是把上面的從左到右改成從上到下。
1 window.onload=function(){ 2 var onld =document.getElementById("onld"); 3 lod(70); 4 var times=null; 5 function lod(top){ 6 clearInterval(times); 7 var onld =document.getElementById("onld"); 8 times=setInterval(function(){ 9 var speen=(top-onld.offsetTop)/20; 10 speen=speen>0?Math.ceil(speen):Math.floor(speen); 11 if(onld.offsetTop==top) 12 { 13 clearInterval(times); 14 }else { 15 onld.style.top=onld.offsetTop+speen+'px'; 16 } 17 },50) 18 } 19 } 20 }
在實際應用中我為了方便 就直接把時間寫死在函數中了,因為在我這個項目中這個函數就只用到一次,不存在代碼復用的問題,為了減少代碼就直接寫死在函數中了。
這個實際應用和上面的案例做的最重要的改動是將offsetLeft改成offsetTop。至於offsetLeft與offsetTop是什么意思看下面這張圖就知道了。(此圖來自百度知道)[圖片不能看的問題已修改]
如果有什么疑問或者建議或者漏洞及錯誤歡迎指正,與我聯系。
——冷小包著
———————————————————————————————————————————————————————————————————————————————
轉載請注明出處及作者。謝謝合作
——冷小包著