Javascript中的运动

一、匀速运动
可以通过offsetLeft/top获取自身的实时位置,在自身的位置的基础上,通过定时器不断执行,每次在自身位置的基础上再加上一个恒定的速度值,即可形成一个简单的匀速运动。

function move1(dom, target) {
            clearInterval(dom.timer);
            dom.timer = setInterval(function () {
                if (dom.offsetLeft == target) {
                    clearInterval(dom.timer);
                    dom.style.left = target + 'px';
                } else {
                    dom.style.left = dom.offsetLeft + 10 + 'px';
                }
             }, 30);
        }

二、缓冲运动
缓冲运动也就是速度由快到慢最后停止的一个过程。而方块的自身动态位置(或透明度)与终点的位置(或透明度)的差值,刚好满足这样一个速度变化的趋势。

	   //缓冲运动
        function move2(dom, target) {
            clearInterval(dom.timer);
            dom.timer = setInterval(function () {
                //offsetLeft越来越大 iSpeed越来越小
                var iSpeed = (target - dom.offsetLeft) / 7;
                //因为offsetLeft取出来会自动取整,忽略小数,最后每次加小数的时候都会死循环将自己变成整数不变,此时将最后加的小数取整,解决这个问题;
                iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                if (dom.offsetLeft == target) {
                    clearInterval(dom.timer);
                    dom.style.left = target + 'px';
                } else {
                    dom.style.left = dom.offsetLeft + iSpeed + 'px';
                }
            }, 30);
        }
        
        //缓冲运动---改变透明度
        //target应是(0-100)之间的数字
        function changeOpacity(dom, target) {
            clearInterval(dom.timer);
            dom.timer = setInterval(function () {
	            //因为透明度的值始终是一个0——1之间的数,速度变化太快,所以给它扩大100倍
                var iCur = parseFloat(getStyle(dom, 'opacity')) * 100;
                var iSpeed = (target - iCur) / 7;
                iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                if (iCur == target) {
                    clearInterval(dom.timer);
                    //因为之前扩大了100倍,此处是将其值还原成0-1之间的数字
                    dom.style.opacity = iCur / 100;
                } else {
                   //因为之前扩大了100倍,此处是将其值还原成0-1之间的数字
                    dom.style.opacity = (iCur + iSpeed) / 100;
                }

            }, 30);
        }

        //多值变化
        // var target = {
        //         'width': 300,
        //         'opacity': 50
        //     }
        function changeMultValue(dom, obj) {
            clearInterval(dom.timer);
            var iCur, iSpeed;
            dom.timer = setInterval(function () {
                var flag = true;
                for (var prop in obj) {
                    if (prop == 'opacity') {
                        iCur = parseFloat(getStyle(dom, prop)) * 100;
                    } else {
                        iCur = parseInt(getStyle(dom, prop));
                    }
                    iSpeed = (obj[prop] - iCur) / 7;
                    iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                    if (prop == 'opacity') {
                        dom.style[prop] = (iCur + iSpeed) / 100;
                    } else {
                        dom.style[prop] = iCur + iSpeed + 'px';
                    }

                    if (iCur != obj[prop]) {
                        flag = false;
                    }
                }
                if (flag) {
                    //所有值都已变化完成后,才清除定时器
                    clearInterval(dom.timer);
                }
            }, 30);
        }

        //多物体多值链式变化
        function changeMult(dom, obj, callback) {
            clearInterval(dom.timer);
            var iCur, iSpeed;
            dom.timer = setInterval(function () {
                var flag = true;
                for (var prop in obj) {
                    if (prop == 'opacity') {
                        iCur = parseFloat(getStyle(dom, prop)) * 100;
                    } else {
                        iCur = parseInt(getStyle(dom, prop));
                    }
                    iSpeed = (obj[prop] - iCur) / 7;
                    iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
                    if (prop == 'opacity') {
                        dom.style[prop] = (iCur + iSpeed) / 100;
                    } else {
                        dom.style[prop] = iCur + iSpeed + 'px';
                    }

                    if (iCur != obj[prop]) {
                        flag = false;
                    }
                }
                if (flag) {
                    clearInterval(dom.timer);
                    typeof callback == 'function' ? callback() : '';
                }
            }, 30);
        }
      
        //多物体多值链式变化调用方式
        // var arr = document.getElementsByTagName('div');
        // var obj = {
        //     left: 400,
        //     top: 100,
        //     width: 400,
        //     height: 400,
        //     opacity: 50
        // };
        // //链式操作  第一个运动完 第二个立马开始
        // arr[0].onclick = function () {
        //     changeMult(this, obj, function () {
        //         changeMult(arr[1], obj,'');
        //     });
        // }
        
      //获取样式
      function getStyle(dom, prop) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(dom, null)[prop];
            } else {
                return dom.currentStyle[prop];
            }
     }

三、弹性运动
1、匀加(减)速运动
通过每次给速度值加上一个固定的值,每次速度都会增加,使之变成一个匀加速的运动;

  //弹性运动1:target左边 速度不断增加  target右边 速度不断减小
        function move1(dom, target) {
            clearInterval(dom.timer);
            var iSpeed = 20;
            var a = 3;
            dom.timer = setInterval(function () {
                if (dom.offsetLeft > target) {
                    iSpeed -= a;
                } else {
                    iSpeed += a;
                }
                dom.style.left = dom.offsetLeft + iSpeed + 'px';
            }, 30);
        }

2、变加(减)速运动

        function move(dom, target) {
            clearInterval(dom.timer);
            var iSpeed = 20;
            var a;
            var u = 0.9;
            dom.timer = setInterval(function () {
                a = (target - dom.offsetLeft) /8;
                // 这里将目标值减去当前位置,这种情况下,当距离目标值越近,分子越小,速度越慢,所以为减速运动;当超过目标值的情况下,速度变成负数,在原来speed的基础上,speed慢慢减少,直到最后变成0,然后变成负数,一旦变成负数,就会开始往反方向也就是往回运动;我们不难发现,其实当物体面向中心的目标值运动时,离得越远,速度越快。离得越近甚至超过中心点的时候,速度一直在减少;就这样一个速度变化的趋势,刚好满足我们所需要的一个弹性运动 ;
                iSpeed += a;
                iSpeed *= u;
                //给一个相当于摩擦系数u,让其速度值越来越接近于0,运动一定程度时停止
                if (Math.abs(iSpeed) < 1 && Math.abs(target - dom.offsetLeft) < 1) {
                //因为当最后速度在减少到非常小的时候,每次乘0.8,会形成很长位数的小数而不会真正归零,所以我们用绝对值判断,只要小于1px我们就让他停止
                    clearInterval(dom.timer);
                } else {
                    dom.style.left = dom.offsetLeft + iSpeed + 'px';
                }
            }, 30);
        }

四、模拟重力场

   var div = document.getElementsByTagName('div')[0];
   div.onmousedown = function (e) {
            clearInterval(div.timer);
            var event = e || window.event;
            var disX = event.clientX - this.offsetLeft;
            var disY = event.clientY - this.offsetTop;
            var lastX = this.offsetLeft;
            var lastY = this.offsetTop;
            document.onmousemove = function (e) {
	            //让方块随着鼠标移动
                var event = e || window.event;
                var nowX = event.clientX - disX;
                var nowY = event.clientY - disY;
                iSpeedX = nowX - lastX;
                iSpeedY = nowY - lastY;

                div.style.left = nowX + 'px';
                div.style.top = nowY + 'px';
                lastX = nowX;
                lastY = nowY;
            }
            document.onmouseup = function () {
                document.onmousemove = null;
                document.onmouseup = null;
                //让方块以最后位置时的速度作为初速度继续运动,相当于惯性运动
                move(div, iSpeedX, iSpeedY)
            }
        }

        function move(dom, iSpeedX, iSpeedY) {
            //进入函数先清除定时器;防止多次触发;
            clearInterval(dom.timer);
            var clientX = getSize().w, clientY = getSize().h, newLeft, newTop;
            var a = 6, u = 0.8;
            dom.timer = setInterval(function () {
                iSpeedY += a;
                newLeft = dom.offsetLeft + iSpeedX;
                newTop = dom.offsetTop + iSpeedY;
                 //运动到四周边界时,变换方向,减小速度
                if (newTop > clientY - dom.offsetHeight) {
                    iSpeedY *= -1;//变换方向
                    iSpeedX *= 0.8;
                    iSpeedY *= 0.8;
                    newTop = clientY - dom.offsetHeight;
                }
                if (newTop < 0) {
                    iSpeedY *= -1;
                    iSpeedX *= 0.8;
                    iSpeedY *= 0.8;
                    newTop = 0;
                }
                if (newLeft > clientX - dom.offsetWidth) {
                    iSpeedX *= -1;
                    iSpeedX *= 0.8;
                    iSpeedY *= 0.8;
                    newLeft = clientX - dom.offsetWidth;
                }
                if (newLeft < 0) {
                    iSpeedX *= -1;
                    iSpeedX *= 0.8;
                    iSpeedY *= 0.8;
                    newLeft = 0;
                }
                if (Math.abs(iSpeedX) <= 1) {
                    iSpeedX = 0;
                }
                if (Math.abs(iSpeedY) <= a * 0.8) {
                    iSpeedY = 0;
                }
                //运动到底部且两个方向上的速度都为0,让其停止,
                if (iSpeedX == 0 && iSpeedY == 0 && newTop == (clientY - dom.offsetHeight)) {
                    clearInterval(dom.timer);
                }
                dom.style.left = newLeft + 'px';
                dom.style.top = newTop + 'px';
            }, 30);
        }
        
     //获取窗口大小
     function getSize() {
            if (window.innerWidth) {
                return {
                    w: window.innerWidth,
                    h: window.innerHeight
                }
            } else if (document.body.clinetWidth) {
                return {
                    w: document.body.clinetWidth,
                    h: document.body.clientHeight
                }
            } else {
                return {
                    w: document.documentElement.clientWidth,
                    h: document.documentElement.clientHeight
                }
            }
        }

你可能感兴趣的:(JavaScript)