JavaScript之运动(各种运动)

一、匀速运动

首先,我们的想法只是简单的向右匀速运动,运用到的是计时器方法。

    <div id="oDiv"></div>
    <span id="oSpan"></span>
    <button id="btn">开始</button>


    <script>
        var oDiv = document.getElementById('oDiv');
        var btn = document.getElementById('btn');
        btn.onclick = function() {
            var iSpend = null;
            setInterval(function() {
                iSpeed = 3;
                oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
            }, 30);
        }
    </script>

此时,div会以30毫秒向右移动3个像素,oDiv.offsetLeft是获取div当前的left值(数值类型),此时存在问题,div会不停的向右运动,下方会出现滚动条,每次点击按钮,div还会加速,加速的原因是因为每点击一次都会触发一个计时器叠加。
优化:
1、我们将span设置成一条黑线,在右方400px位置,让div到位置自动停下。
2、每次点击会将计时器清空一次,重新建立一个计时器,解决加速问题。
直接看优化代码

<div id="oDiv"></div>
    <span id="oSpan"></span>
    <button id="btn">开始</button>

    <script>
        var oDiv = document.getElementById('oDiv');
        var btn = document.getElementById('btn');
        var timer = null;
        btn.onclick = function() {
            clearInterval(timer);
            var iSpend = null;
            timer = setInterval(function() {
                iSpeed = 4;
                oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
                if (oDiv.offsetLeft == 400) {
                    clearInterval(timer);
                }
            }, 30);
        }
    </script>

看效果图
在这里插入图片描述
上面代码我们将iSpeed设置成4,是400的倍数,在判断位置的时候刚好能在指定位置停下,此时又存在两个问题。
新的问题
1、如果iSpeed的值不能被400整除,div将不会停下
2、如果div在固定位置的右边
在优化这两个问题同时,我们把这个匀速运动功能封装成函数。

<script>
        var oDiv = document.getElementById('oDiv');
        var btn = document.getElementById('btn');
        btn.onclick = function() {
            startMove(oDiv, 400)
                // clearInterval(timer);
                // timer = setInterval(function() {
                //     var iSpeed = -oDiv.offsetLeft;
                //     oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
                //     if (oDiv.offsetLeft == 400) {
                //         clearInterval(timer);
                //     }
                // }, 30);
        }

        function startMove(dom, target) {
            var timer = null;
            clearInterval(timer);
            var iSpeed = target - dom.offsetLeft > 0 ? 7 : -7;
            timer = setInterval(function() {
                if (Math.abs(target - dom.offsetLeft) < Math.abs(iSpeed)) {
                    clearInterval(timer);
                    dom.style.left = target + 'px';
                } else {
                    dom.style.left = dom.offsetLeft + iSpeed + 'px';
                }
            }, 30);
        }
    </script>

上面的div的left的值被设置为700px,截止到此,匀速运动问题基本解决。

二、缓冲运动

物体的速度 距离目标点越近 就越小 当到达目标点时 速度减小为0

        var oDiv = document.getElementById('oDiv');
        var btn = document.getElementById('btn');
        btn.onclick = function () {
               startMove(oDiv, 400);
           }
           function startMove (dom, target) {
               clearInterval(timer);
               var iSpeed = null,timer = null;
               timer = setInterval(function () {
                   iSpeed = (target - oDiv.offsetLeft) / 7;
                   iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                   if (oDiv.offsetLeft == target) {
                       clearInterval(timer);
                   }else {
                       oDiv.style.left = oDiv.offsetLeft + iSpeed + 'px';
                   }
               }, 30);
            }

Math.ceil() “向上取整”, 即小数部分直接舍去,并向正数部分进1
Math.floor() “向下取整” ,即小数部分直接舍去

透明度缓冲变化

<div id="oDiv"></div>
    <span id="oSpan"></span>
    <button id="btn">开始</button>


    <script>
        var oDiv = document.getElementById('oDiv');
        var btn = document.getElementById('btn');
        btn.onclick = function() {
            startMove(oDiv, 50);
            }
        function getStyle(dom, attr) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[attr];
            } else {
                return dom.currentStyle[attr];
            }
        }

        function startMove(dom, target) {
            var timer = null;
            clearInterval(timer);
            var iSpeed = null,
                iCur = null;
            timer = setInterval(function() {
                iCur = parseFloat(getStyle(dom, 'opacity')) * 100;
                iSpeed = (target - iCur) / 7;
                iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                if (iCur == target) {
                    clearInterval(timer);
                } else {
                    // 0 - 1    iCur * 100 target * 100 iSpeed * 100  iCur + iSpeed 0 - 100 /  100
                    dom.style.opacity = (iCur + iSpeed) / 100;
                }
            }, 30);
        }

点击之后,div颜色慢慢变成0.5

多物体运动

    <div></div>
    <div></div>
    <div></div>
    <div></div> 
    var oDivArray = document.getElementsByTagName('div');
    for (var i = 0; i < oDivArray.length; i++) {
               oDivArray[i].onmouseenter = function () {
                   startMove(this, 400);
               }
               oDivArray[i].onmouseleave = function () {
                   startMove(this, 100);
               }
           }
           function getStyle(dom, attr) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[attr];
            } else {
                return dom.currentStyle[attr];
            }
        }
           function startMove (dom, target) {
           var timer = null;
               clearInterval(dom.timer);
               var iSpeed = null, iCur = null;
               dom.timer = setInterval(function () {
                   iCur = parseInt( getStyle(dom, 'width') );
                   iSpeed = ( target - iCur ) / 7;
                   // .... 
                   iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                   if (iCur == target) {
                       clearInterval(dom.timer);
                   }else {
                       dom.style.width = iCur + iSpeed + 'px';
                   }
               }, 30);
           }   

多物体不同值的运动

    <div></div>
    <div></div>
    <div></div>
    <div></div> 
          var timer = null;
           var oDivArray = document.getElementsByTagName('div');

           oDivArray[0].onclick = function () {
               startMove(this, 'width', 400);
           }

           oDivArray[1].onclick = function () {
               startMove(this, 'height', 400);
           }
           oDivArray[2].onclick = function () {
               startMove(this, 'borderWidth', 20);
           }

           oDivArray[3].onclick = function () {
               startMove(this, 'opacity', 50);
           }
           function getStyle (dom, attr) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[attr];
            }else {
                return dom.currentStyle[attr];
            }
        }
        function startMove (dom, attr, target) {
               clearInterval(dom.timer);
               var iSpeed = null, iCur = null;
               dom.timer = setInterval(function () {
                   if (attr == 'opacity') {
                       iCur = parseFloat( getStyle(dom, attr) ) * 100;
                   }else {
                       iCur = parseInt( getStyle(dom, attr) );
                   }
                   iSpeed = (target - iCur) / 7;
                   iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                   if (iCur == target) {
                       clearInterval(dom.timer);
                   }
                   if (attr == 'opacity') {
                       dom.style.opacity = ( iCur + iSpeed ) / 100;
                   }else {
                       dom.style[attr] = iCur + iSpeed + 'px';
                   }   
               }, 30);
           }

四个不同的div各自变化各自的一个值

多物体多值运动+回调机制

        div {
            position: absolute;
            left: 0px;
            width: 100px;
            height: 100px;
            background: red;
            opacity: 1;
        }
        #topDiv {
            top: 200px;
        }
        #bottomDiv {
            top: 400px;
        }
    <div id='topDiv'></div>
    <div id="bottomDiv"></div>
    <script>
        // js div
        // width -> 100 400   height 100 400   left 0 200  top 200 300 opacity 1 0.5
        // {width: 400, height: 400, left: 200, top: 300, opacity: 50}

        var oTopDiv = document.getElementById('topDiv');
        var oBottomDiv = document.getElementById('bottomDiv');
        oTopDiv.onclick = function () {
            startMove(this, {width: 400, height: 400, left: 200, top: 300, opacity: 50}, function () {
                startMove(oBottomDiv, {width: 400, height: 400, left: 200, top: 300, opacity: 50}, function () {
                    alert('over');
                })
            })
        }
        function getStyle (dom, attr) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[attr];
            }else {
                return dom.currentStyle[attr];
            }
        }

        function startMove (dom, attrObj, callback) {
            clearInterval(dom.timer);
            var iSpeed = null, iCur = null;
            dom.timer = setInterval(function () {
                var bStop = true;
                for (var attr in attrObj) {
                    // 'width' 'height' 
                    if (attr == 'opacity') {
                        iCur = parseFloat( getStyle(dom, attr) ) * 100;
                    }else {
                        iCur = parseInt( getStyle(dom, attr) );
                    }
                    iSpeed = (attrObj[attr] - iCur) / 7;
                    iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                    if (attr == 'opacity') {
                       dom.style.opacity = (iCur + iSpeed) / 100; 
                    }else {
                       dom.style[attr] = iCur + iSpeed + 'px';
                    }
                    if (iCur != attrObj[attr]) {
                        bStop = false;
                    }
                }
                if (bStop) {
                    clearInterval(dom.timer);
                    typeof callback == 'function' && callback();
                }
            }, 30);
        }

运动基本上就结束了,之后还有加速运动、弹性运动等

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值