js模擬拋物運動和慣性運動

751371041發表於2020-11-10

js模擬拋物運動和慣性運動

一.普通移動

利用請求動畫幀requesrannamitionframe()----16.67ms執行一次

1.佈局

<body>
    <div class="wrap">
       <div class="ball"></div>
</div>
    
</body>

2.CSS樣式

 <style>
        .wrap{
            width: 1200px;
            height: 600px;
            background-color: aqua;
            margin: 50px auto;
            position: relative;
        }
        .ball{
            width: 100px;
            height: 100px;
            background-color: red;
/* 設定圓角*/
            border-radius: 50%;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>

3.js實現(遞迴函式實現)

 <script>
        var spX = 3;
        var spY = 3;
        var oB = document.querySelector(".ball");
        var oW = document.querySelector(".wrap");
requestAnimationFrame(function moveBall (){
                  oB.style.left = oB.offsetLeft+spX+"px";
                    oB.style.top =oB.offsetTop+spY+"px";
requestAnimationFrame(moveball);//遞迴函式持續進行
}

二.在固定範圍內運動

*大於最大值就把當前最大值給他並且速度取反

requestAnimationFrame(function moveBall (){
                    var wL = oB.offsetLeft + spX;
                    var wT = oB.offsetTop + spY;
//右
                    if(wL>=oW.offsetWidth-oB.offsetWidth){
                        wL = oW.offsetWidth-oB.offsetWidth;
                        spX = -spX;
                    }
//左
                    if(wL<=0){
                        wL = 0;
                        spX = -spX;
                    }
//下
                    if(wT>=oW.offsetHeight-oB.offsetHeight){
                        wT = oW.offsetHeight-oB.offsetHeight;
                        spY = -spY;
                    }
//上
                    if(wT<=0){
                        wT = 0;
                        spY = -spY;
                    }
                    oB.style.left = wL + "px";
                    oB.style.top = wT + "px";
                    requestAnimationFrame(moveBall);
                })

三.在丟擲的方向繼續移動

*換算速度進行求解

//一幀代表兩次onmousemove的時間間隔

<script>
        // 往那個方向仍就往哪個方向移動
        var spX = 3;
        var spY = 3;
        var oB = document.querySelector(".ball");
        var oW = document.querySelector(".wrap");
        oB.onmousedown = function (){
            var oBOff = offsetWindow(this);
            var disX = event.pageX - oBOff[0];
            var disY = event.pageY - oBOff[1];
            //時間
            var oldT = 0;
            var newT = 0;
            var chaT = 0;
            //位置
            var oldP = [0,0];
            var newP = [0,0];
            var chaX = 0;
            var chaY = 0;
            document.onmousemove = function (){
                var oWOff = offsetWindow(oW);
                var wL = event.pageX - disX - oWOff[0];
                var wT = event.pageY - disY - oWOff[1];
                wL = Math.max(0,wL);
                wL = Math.min(oW.offsetWidth-oB.offsetWidth,wL);
                wT = Math.max(0,wT);
                wT = Math.min(oW.offsetHeight-oB.offsetHeight,wT);
                oB.style.left = wL + "px";
                oB.style.top = wT + "px";
             //得到新位置新時間
                newT = new Date().getTime();
                newP[0] = wL;
                newP[1] = wT;
                chaT = newT - oldT;
                chaX = newP[0] - oldP[0];
                chaY = newP[1] - oldP[1];
                oldT = newT;
                oldP[0] = newP[0];
                oldP[1] = newP[1];
            }
            document.onmouseup = function (){
                spX = chaX*16.67 / chaT;
                //spX=chaX/chaT;表示1ms的走過的距離速度
                spY = chaY*16.67 / chaT;
                //得到速度開啟計時器
                requestAnimationFrame(function moveBall (){
                    var wL = oB.offsetLeft + spX;
                    var wT = oB.offsetTop + spY;
                    if(wL>=oW.offsetWidth-oB.offsetWidth){
                        wL = oW.offsetWidth-oB.offsetWidth;
                        spX = -spX;
                    }
                    if(wL<=0){
                        wL = 0;
                        spX = -spX;
                    }
                    if(wT>=oW.offsetHeight-oB.offsetHeight){
                        wT = oW.offsetHeight-oB.offsetHeight;
                        spY = -spY;
                    }
                    if(wT<=0){
                        wT = 0;
                        spY = -spY;
                    }
                    oB.style.left = wL + "px";
                    oB.style.top = wT + "px";
                    requestAnimationFrame(moveBall);
                })
          //清空原有效果
                document.onmousemove = document.onmouseup = null;
            }
            stopDefault(event);
        }
        
    </script>

四.模擬帶有重力加速的的場景

   *速度隨之越來越快

               末尾賦值  oB.style.left = wL + "px";
                            oB.style.top = wT + "px";

              後spY+=0.3;

五.帶有摩擦效果

  變化使speed*0.85....

   速度損耗,慢慢停下來

        致使判斷終點關閉計時器

  <script>
        var oW = document.querySelector(".wrap");
        var oB = document.querySelector(".ball");
        var spX = 5;
        var spY = 3;
        var timer = requestAnimationFrame(function moveBall (){
            timer = requestAnimationFrame(moveBall);
            var wL = oB.offsetLeft + spX;
            var wT = oB.offsetTop + spY;
            if(wL>=oW.offsetWidth-oB.offsetWidth){
                wL = oW.offsetWidth-oB.offsetWidth;
                spX = -spX*0.9;
                spY = spY*0.9;
            }
            if(wL<=0){
                wL = 0;
                spX = -spX*0.9;
                spY = spY*0.9;
            }
            if(wT>=oW.offsetHeight-oB.offsetHeight){
                wT = oW.offsetHeight-oB.offsetHeight;
                //判斷速度,關閉計時器,停在終點
                spY = -spY*0.9;
                spX = spX*0.9;
                if(Math.abs(spY)<=1.5&&Math.abs(spX)<=1.5){
                    cancelAnimationFrame(timer);
                }
            }
            if(wT<=0){
                wT = 0;
                spY = -spY*0.95;
            }
            oB.style.left = wL + "px";
            oB.style.top = wT + "px";
            spY += 0.3;
            
        })
    </script>

 

相關文章