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是什么意思看下面这张图就知道了。(此图来自百度知道)
如果有什么疑问或者建议或者漏洞及错误欢迎指正,与我联系。
——冷小包著
———————————————————————————————————————————————————————————————————————————————
转载请注明出处及作者。谢谢合作
——冷小包著