js-运动总结(常见运动效果)

  1. 匀速运动
  2. 加速运动
  3. 缓冲运动
  4. 碰撞运动
  5. 重力运动
  6. 多物体多值多链式运动框架
1. 匀速运动

速度isSpeed是个定值

function startmov(obj) {
            clearInterval(timer);
            var isSpeed = 10;
            timer = setInterval(function () {
                obj.style.left = obj.offsetLeft + isSpeed + 'px';
            },30);
        }
2. 变速运动

核心就是isSpeed每次执行发生改变

// 变速运动
        function starSpeedChangeMove(obj,target) {
            clearInterval(timer);
            var isSpeed;
            timer = setInterval(function () {
                isSpeed = (target - obj.offsetLeft) / 15;
                isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed);
                obj.style.left = obj.offsetLeft + isSpeed + 'px';
            },30);
        }
应用(伸缩栏)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .wrapper{
        position : absolute;
        top: 200px;
        left: -400px;
        width: 400px;
        height: 100px;
        background: yellowgreen;
    }
    .demo{
        position: absolute;
        top: 0;
        left: 400px;
        width: 40px;
        height: 100px;
        background: yellow;
    }
    </style>
</head>
<body>
    
    <div class="wrapper">
        <div class="demo">

        </div>
    </div>

    <script>

        var oDivDemo = document.getElementsByClassName('wrapper')[0];
        var timer = null;
        oDivDemo.onmouseenter = function () {
            starSpeedChangeMove(this,0);
        }
        oDivDemo.onmouseleave = function () {
            
            starSpeedChangeMove(this,-400);
        }
        
        function starSpeedChangeMove(obj,target) {
            clearInterval(timer);
            var isSpeed;
            timer = setInterval(function () {
                isSpeed = (target - obj.offsetLeft) / 15;
                isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed);
                obj.style.left = obj.offsetLeft + isSpeed + 'px';
            },30);
        }
    </script>
</body>
</html>
3. 缓冲运动

顾名思义,所谓缓冲,就是说速度不同;在一定条件下,距离越大,速度越大;距离越小,速度也就越小。
也就是跟变速运动差不多代码

4.碰撞运动(弹性运动)

在发生碰撞的时候,我们把对应的x,y方向的速度乘以"摩擦系数"

// 弹性运动
        function starMove (obj, target) {
            clearInterval(obj.timer);
            var isSpeed = 20;
            var a, u = 0.8;  // u表示摩擦系数
            obj.timer = setInterval(function (){
                a = (target - obj.offsetLeft) / 15;
                isSpeed = isSpeed + a;
                isSpeed = isSpeed * 0.9;
                if(Math.abs(isSpeed) < 1 && Math.abs(target - obj.offsetLeft) < 1){
                    clearInterval(obj.timer);
                }else{
                    obj.style.left = obj.offsetLeft + isSpeed + 'px'; 
                }
                
                
            },30);
        }
应用(弹性导航栏)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        *{
            margin: 0px;
            padding: 0px;
            list-style: none;
        }
        ul{
            position: relative;
            width: 600px;
            height: 80px;
            /* border: 1px solid #000; */
            margin : 100px auto 0;
        }
        ul li.nav{
            width: 148px;
            height: 78px;
            border: 1px solid #000;
            color : #000;
            text-align: center;
            line-height: 78px;
            float: left;
        }
        ul li.bg{
            position: absolute;
            top: 0px;
            left: 0px;
            width: 150px;
            height: 80px;
            background: rgb(214, 49, 49);
            z-index: -1;
        }
    </style>
</head>
<body>
    
    
    <ul>
        <li class="nav">ES6</li>
        <li class="nav">Webpack</li>
        <li class="nav">Vue</li>
        <li class="nav">Node</li>
        <li class="bg"></li>
    </ul>
    
    <script>
        
        var oLi = document.getElementsByTagName('li');
        var oBg = document.getElementsByClassName('bg')[0];
        var oLiArr = Array.prototype.slice.call(oLi, 0);
        oLiArr.forEach(function (ele, index){
            ele.onmouseenter = function (){
                starMove(oBg,this.offsetLeft);
            }
        });
        
        function starMove (obj, target) {
            clearInterval(obj.timer);
            var isSpeed = 20;
            var a, u = 0.8;  // u表示摩擦系数
            obj.timer = setInterval(function (){
                a = (target - obj.offsetLeft) / 15;
                isSpeed = isSpeed + a;
                isSpeed = isSpeed * 0.9;
                if(Math.abs(isSpeed) < 1 && Math.abs(target - obj.offsetLeft) < 1){
                    clearInterval(obj.timer);
                }else{
                    obj.style.left = obj.offsetLeft + isSpeed + 'px'; 
                }
                
                
            },30);
        }
    </script>
</body>
</html>
5. 重力运动
// targetSpeedX,targetSpeedY 表示的是x,y速度矢量值
        function starMove (obj,targetSpeedX,targetSpeedY){
            clearInterval(obj.timer);
            var iSpeedX,
                iSpeedY,
                g = 10,     // 重力加速度
                u = 0.8;   // 碰撞时速度损失
            iSpeedX = (typeof targetSpeedX == 'undefined' ? 6 : targetSpeedX),
            iSpeedY = (typeof targetSpeedY == 'undefined' ? 8 : targetSpeedY);
            console.log(iSpeedY,iSpeedX);
            obj.timer = setInterval(function (){
                iSpeedY += g;
                var newLeft = obj.offsetLeft + iSpeedX,
                    newTop = obj.offsetTop + iSpeedY;
                // 边界处理
                if(newTop >= document.documentElement.clientHeight - obj.offsetHeight){
                    iSpeedY *= -1;
                    iSpeedY *= u;
                    iSpeedX *= u;
                    newTop = document.documentElement.clientHeight - obj.offsetHeight;

                }
                if(newTop <= 0){
                    iSpeedY *= -1;
                    iSpeedY *= u;
                    iSpeedX *= u;
                    newTop = 0;
                }
                if(newLeft >= document.documentElement.clientWidth - obj.offsetWidth){
                    iSpeedX *= -1;
                    iSpeedX *= u;
                    newLeft = document.documentElement.clientWidth - obj.offsetWidth;
                }
                if(newLeft <= 0){
                    iSpeedX *= -1;
                    iSpeedX *= u;
                    newLeft = 0; 
                }
                // 判断结束条件
                if(Math.abs(document.documentElement.clientHeight-obj.offsetHeight-newTop) < 1 && Math.abs(iSpeedY) < 1){
                    clearInterval(obj.timer); 
                }else{
                    obj.style.left = newLeft + 'px';
                    obj.style.top = newTop + 'px';
                }
            },30);
        }
应用(拖拽抛出效果)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body{
            overflow: hidden;
        }
        .demo{
            position: absolute;
            left: 0px;
            top: 0px;
            width: 100px;
            height: 100px;
            border-radius: 50%;
            background: #000;
        }
    </style>
</head>
<body>
    
    <div class="demo"></div>
    <script>
        var oDiv = document.getElementsByClassName('demo')[0];

        // oDiv.onclick = function (){
        //     starMove(this,1,1); 
        // }
        var lastX = oDiv.offsetLeft,
            lastY = oDiv.offsetTop;
        oDiv.onmousedown = function (e) {
            var event = e || window.event;
            var disX = event.clientX - this.offsetLeft,
                disY = event.clientY - this.offsetTop,
                that = this;
            var iSpeedX = 0,
                iSpeedY = 0;
            document.onmousemove = function (e) {

                var newLeft = e.clientX - disX,
                    newTop = e.clientY - disY;
                    iSpeedX = newLeft - lastX,
                    iSpeedY = newTop - lastY,
                    lastX = newLeft,
                    lastY = newTop;
                that.style.left = newLeft + 'px';
                that.style.top = newTop + 'px';
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    //iSpeedX,iSpeedY 相当于是速度的方向差值  正负表示方向
                    starMove(that,iSpeedX,iSpeedY);
                }
            }
        }

        // 模拟重力场   
        // targetSpeedX,targetSpeedY 表示的是x,y速度矢量值
        function starMove (obj,targetSpeedX,targetSpeedY){
            clearInterval(obj.timer);
            var iSpeedX,
                iSpeedY,
                g = 10,     // 重力加速度
                u = 0.8;   // 碰撞时速度损失
            iSpeedX = (typeof targetSpeedX == 'undefined' ? 6 : targetSpeedX),
            iSpeedY = (typeof targetSpeedY == 'undefined' ? 8 : targetSpeedY);
            console.log(iSpeedY,iSpeedX);
            obj.timer = setInterval(function (){
                iSpeedY += g;
                var newLeft = obj.offsetLeft + iSpeedX,
                    newTop = obj.offsetTop + iSpeedY;
                // 边界处理
                if(newTop >= document.documentElement.clientHeight - obj.offsetHeight){
                    iSpeedY *= -1;
                    iSpeedY *= u;
                    iSpeedX *= u;
                    newTop = document.documentElement.clientHeight - obj.offsetHeight;

                }
                if(newTop <= 0){
                    iSpeedY *= -1;
                    iSpeedY *= u;
                    iSpeedX *= u;
                    newTop = 0;
                }
                if(newLeft >= document.documentElement.clientWidth - obj.offsetWidth){
                    iSpeedX *= -1;
                    iSpeedX *= u;
                    newLeft = document.documentElement.clientWidth - obj.offsetWidth;
                }
                if(newLeft <= 0){
                    iSpeedX *= -1;
                    iSpeedX *= u;
                    newLeft = 0; 
                }
                // 判断结束条件
                if(Math.abs(document.documentElement.clientHeight-obj.offsetHeight-newTop) < 1 && Math.abs(iSpeedY) < 1){
                    clearInterval(obj.timer); 
                }else{
                    obj.style.left = newLeft + 'px';
                    obj.style.top = newTop + 'px';
                }
            },30);
        }
    
    </script>
</body>
</html>
6. 多物体多值多链式运动框架

多物体运动:
让每一个运动的物体拥有自己的定时器 定时器独立
把定时器作为对象的属性 让定时器独立

链式运动
上一个动作结束 进入到下一个动作
解决 : 在运动函数上加一个参数,参数代表回调函数

参数说明:obj 对应元素,
json 对象, 属性是改变的样式,比如 width height opacity
callback 回调函数 可以进行多个动作发生
小技巧: opacity 改变的时候,可以把isSpeed扩大100倍,最后在缩小100倍

function startMove(obj, json, callback){
            clearInterval(obj.timer);
            obj.timer = setInterval(function (){
                var oBstop = true,
                    isSpeed,
                    iCur;
                for(var attr in json){
                    if(attr == 'opacity'){
                        iCur = parseFloat(getStyle(obj,attr)) * 100;
                    }else{
                        iCur = parseInt(getStyle(obj,attr));
                    }
                    isSpeed = (json[attr] - iCur) / 7;
                    isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed);
                    if(attr == 'opacity'){
                        obj.style.opacity = (isSpeed + iCur) / 100;
                    }else{
                        obj.style[attr] = (isSpeed + iCur) + 'px';
                    }
                    if(json[attr] != iCur){
                        oBstop = false;
                    }
                }
                if(oBstop){
                    clearInterval(obj.timer);
                    typeof callback == 'function' ? callback() : "";
                }
            },30);
        }
demo(具体用法)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div{
            position : absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background : red;
            opacity: 1;
            border : 1px solid #000;
            margin: 100px;
        }
        .top {
            top : 100px;
        }
        .buttom {
            bottom : 100px;
        }
    </style>
</head>
<body>
    
    <div class="top">1</div>
    <div class="buttom">2</div>
    <script>
        

        var oDiv = document.getElementsByTagName('div');
        var timer = null;
        var targetObj = {
            width : 400,
            height : 400,
            opacity : 20,
            left : 200,
            top : 200
        }
        oDiv[0].onclick = function (){
            startMove(this,targetObj,function (){
                console.log('this == ', this);
                startMove(oDiv[1],targetObj);
            });
            console.log(222);
        }
        // 多物体多链式运动框架
        
        function getStyle (obj, attr) {
            if(obj.currentStyle){
                return obj.currentStyle[attr];
            }else{
                return window.getComputedStyle(obj,false)[attr];
            }
        }
        function startMove(obj, json, callback){
            clearInterval(obj.timer);
            obj.timer = setInterval(function (){
                var oBstop = true,
                    isSpeed,
                    iCur;
                for(var attr in json){
                    if(attr == 'opacity'){
                        iCur = parseFloat(getStyle(obj,attr)) * 100;
                    }else{
                        iCur = parseInt(getStyle(obj,attr));
                    }
                    isSpeed = (json[attr] - iCur) / 7;
                    isSpeed = isSpeed > 0 ? Math.ceil(isSpeed) : Math.floor(isSpeed);
                    if(attr == 'opacity'){
                        obj.style.opacity = (isSpeed + iCur) / 100;
                    }else{
                        obj.style[attr] = (isSpeed + iCur) + 'px';
                    }
                    if(json[attr] != iCur){
                        oBstop = false;
                    }
                }
                if(oBstop){
                    clearInterval(obj.timer);
                    typeof callback == 'function' ? callback() : "";
                }
            },30);
        }
    </script>
</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值