JavaScript暑期学习(五)

JS运动基础

利用定时器实现运动原理,大致框架:

  • 清除定时器
  • 创建定时器函数
  • 函数中if(到达目标值){清除定时器}-else{进行操作}判断
  • 设置事件处理函数

一、三个简单实例-无缓冲运动

1.点击按钮运动的方块

点击按钮,方块向左运动,到达300px位置停止。
   <script>
        var timer=null;
        function startMove()
        {
            var oDiv=document.getElementById('div1');
            clearInterval(timer);
            timer=setInterval(function () {
                var speed=1;
                if(oDiv.offsetLeft>=300)
                {
                    clearInterval(timer);
                }
                else
                {
                    oDiv.style.left=oDiv.offsetLeft+speed+'px';
                }
            },30);
        }
   </script>
  1. 利用if判断是否到达目标,以此为根据来停止运动。
  2. 要首先清除定时器再设置定时器,否则会同时开启很多计时器,造成运动速度发生变化。

2.鼠标悬停会出现的侧栏

一开始方块隐藏在左边看不到,鼠标移动到分享上,侧栏从左边出现,移开鼠标后侧栏又恢复到看不见的位置
<script>
    window.onload=function () 
    {
        var oDiv=document.getElementById('div1');
        oDiv.onmouseover=function () {
            Move(0);
        }
        oDiv.onmouseout=function () {
            Move(-150);
        }
    };
    var timer=null;
    function Move(target) {
        var oDiv=document.getElementById('div1');
        clearInterval(timer);
        timer=setInterval(function () {
            var speed=0;
            if(oDiv.offsetLeft>target)
            {
                speed=-10;
            }
            else
            {
                speed=10;
            }
            if(oDiv.offsetLeft==target)
            {
                clearInterval(timer);
            }
            else
            {
                oDiv.style.left=oDiv.offsetLeft+speed+'px';
            }
        },30);
    }
</script>

通过控制目标值参数用一个函数实现移入和移出运动。

3.透明度变化

颜色为red,初始透明度30,鼠标移入后慢慢变成100,移出后又慢慢回到30
<script>
        window.onload=function()
        {
            var oDiv=document.getElementById('div1');
            oDiv.onmouseover=function()
            {
                startMove(100);
            }
            oDiv.onmouseout=function () {
                startMove(30);
            }
        }
        var alpha=30;
        var timer=null;
        function startMove(target) {
            var oDiv=document.getElementById('div1');
            clearInterval(timer);
            timer=setInterval(function () {
                var speed=0;
                if(alpha<target)
               {
                   speed=1
               }
                else
                {
                    speed=-1;
                }
                if(alpha==target)
               {
                   clearInterval(timer);
               }
               else
               {
                    alpha+=speed;
                    oDiv.style.filter='alpha(opacity:'+alpha+')';
                    oDiv.style.opacity=alpha/100;
               }
            },30);
        }
</script>

由于没有获取透明度的操作,于是我们用变量储存透明度的值,再将这个值的变化传给元素。这里为了兼容性,所以用了两种方式来操作透明度。

二、缓冲运动简单实例+匀速运动改进

1.简单方块的缓冲运动

方块速度越来越小最后停在目标位置
<script>
        function startMove() {
            var oDiv=document.getElementById('div1');
            setInterval(function(){
                var speed=(300-oDiv.offsetLeft)*0.05;
                speed=speed>0?Math.ceil(speed):Math.floor(speed);//缓冲运动的取整问题
                oDiv.style.left=oDiv.offsetLeft+speed+'px';
            },30);
        }
    </script>

缓冲运动的特别之处就在于速度与距离成正比,处理好速度是关键。首先,1像素是最小单位,小数点后的数字会被忽略,如果不进行相应的取整操作可能会导致还没到指定位置就停下的bug。用Math.ceil()向上取整和Math.floor()向下取整的if判断解决缓冲运动的速度取整问题。

2.位置不变的侧栏悬浮框

滚动条滚动时,悬浮框会以缓冲运动始终停止在视窗中部。
<script>
    window.onscroll=function () {
        var oDiv=document.getElementById('div1');
        var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
        startMove(parseInt((document.documentElement.clientHeight-oDiv.offsetHeight)/2+scrollTop));//取整问题
    };
    var timer=null;
    function startMove(target)
    {
        var oDiv=document.getElementById('div1');
        clearInterval(timer);
        timer=setInterval(function () {
            var speed=(target-oDiv.offsetTop)/6;
            speed=speed>0?Math.ceil(speed):Math.floor(speed);
            if(oDiv.offsetTop==target)
            {
                clearInterval(timer);
            }
            else
            {
                document.getElementById('txt1').value=oDiv.offsetTop;
                oDiv.style.top=oDiv.offsetTop+speed+'px';
            }
        },30);
    }
</script>

首先,这是我第一个使用滚动条的小练习。设置body高度为视窗肯定装不下的高度,浏览器页面会自动配置滚动条。明确悬浮框的顶部距离=视窗距离页面顶部的高度+悬浮框距离视窗顶部的高度【即(视窗高度-悬浮窗高度)/2】。这里面临一个新的问题,是目标值取整问题,由于我们有除以2的操作使得可能出现结果为小数造成悬浮窗上下抖动。利用parseInt()函数解决。

3.匀速运动停止——改进

距离除以速度除不尽的情况下,方块仍能精准到达目标位置。
<script>
        var timer=null;
        function startMove(target) {
            var oDiv=document.getElementById('div1');
            var speed=0;
            clearInterval(timer);
            timer=setInterval(function(){
                if(oDiv.offsetLeft<target)
                {
                    speed=7;
                }
                else
                {
                    speed=-7;
                }
                if(Math.abs(target-oDiv.offsetLeft)<=7)
                {
                    clearInterval(timer);
                    oDiv.style.left=target+'px';
                }
                else
                {
                    oDiv.style.left=oDiv.offsetLeft+speed+'px';
                }
            },30);
        }
</script>

利用绝对值函数判断,当与目标的距离小于速度时,关掉计时器并令方块直接到达目标值,就能在人眼察觉不到的变化中令方块好似不管速度是多少都能匀速到达目标位置。

总结

今天通过六个简单的小例子学习了简单的JS运动,记住了一般运动框架,也感受到了JS运动的魅力,同时在练习中学到了一些新的知识。对于设计思路也有了一定帮助,加油加油加油~~~明天也要更厉害哟!

发表评论

电子邮件地址不会被公开。 必填项已用*标注