JS+dom簡單運動實現


先進行一個簡單的方向運動

此網頁主要實現對一個dom元素的運動方向控制及運動狀態控制

HTML主要代碼如下:

<div id="obj"></div>
<button>tUp</button>
<button>tRight</button>
<button>tDown</button>
<button>tLeft</button>
<button>Quicker</button>
<button>Slower</button>
<button>Stop</button>

JS主要代碼如下:


    //獲取運動目標元素,並初始化其樣式
    var obj = document.getElementById("obj");
    obj.style.position = "absolute";
    obj.style.height = "20px";
    obj.style.width = "20px";
    obj.style.borderRadius = "50%";
    obj.style.background = "skyblue";
    
    //獲取按鈕
    var btn = document.getElementsByTagName("button");

    //初速度
    var speedX = 5, speedY = 5;

    //設置定時器,實現運動
    obj.t = setInterval( function() {//將該定時器設為obj專屬
        obj.style.left = obj.offsetLeft + speedX + "px";
        obj.style.top = obj.offsetTop + speedY + "px";

        //觸碰邊界時反彈
        if ( ( ( document.body.offsetWidth - obj.offsetLeft ) < obj.offsetWidth ) || obj.offsetLeft <= 0 ) {
            speedX *= -1;
        }
        if ( ( ( document.body.offsetHeight - obj.offsetTop ) < obj.offsetHeight ) || obj.offsetTop <= 0 ) {
            speedY *= -1;
        }
    }, 30);

        //按鈕控制方向
        for ( var i = 0; i < btn.length; i ++ ) {
            btn[i].dire = i;
            btn[i].onclick = function() {
                switch( btn[i].dire ) {
                    case 0: speedY = -Math.abs( speedY ); break;
                    case 1: speedX = Math.abs( speedX ); break;
                    case 2: speedY = Math.abs( speedY ); break;
                    case 3: speedX = -Math.abs( speedX ); break;
                    case 4: speedX = speedX > 0 ? ++speedX : --speedX; speedY = speedY > 0 ? ++speedY : --speedY; break;
                    case 5: speedX = speedX > 0 ? --speedX : ( speedX == 0 ? 0 : ++speedX ); speedY = speedY > 0 ? --speedY : ( speedY == 0 ? 0 : ++speedY ); break;
                    case 4: speedX = 0; speedY = 0;
                }
            }
        }

預覽:http://htmlpreview.github.io/?https://github.com/shockw4ver/JavaScriptCases/blob/master/JSSports/方塊運動.html

然后是拋物線運動

拋物線運動的軌跡需要進行計算,按照拋物線公式ax^x+bx+c=y,我們需要得知a、b、c的值才能得知這個軌跡,這樣看起來難以馬上得知,但通過一點技巧就不同了。

對於a、b、c三個參數,a代表曲率,在沒有要求的情況下可以自行設定,因為不管如何的曲率,配合某個b的值都能到達目的坐標;而c就更容易去掉了,c代表拋物線的偏移,如果我們將起點作為坐標系起點,c的值就可以直接忽略了。

html主要代碼如下:

<div id="ball"></div>
<div id="target"></div>

一點簡單的css樣式:

#ball {
    height: 20px;
    width: 20px;
    background: brown;
    border-radius: 50%;
    position: absolute;
    left: 10px;
    top: 400px;
}
		
#target {
    height: 20px;
    width: 20px;
    background: skyblue;
    position: absolute;
    right: 300px;
    top: 100px;
    opacity: 0.6;
}

JS主要代碼:

    var ball = document.getElementById("ball");
    //目標位置
    var target = {
        X : document.getElementById("target").offsetLeft,
        Y : document.getElementById("target").offsetTop
    }

    //將起點定義為圓心
    var centerPoint = {
        X : ball.offsetLeft,
        Y : ball.offsetTop
    }

    //"圓心"坐標
    var x = centerPoint.X, y = centerPoint.Y;

    //拋物線公式參數
    var a = 0.0008; //曲率,若無要求,自己定義就行了
    var b = ( target.Y - a*target.X*target.X ) / target.X;//根據目的坐標和a來計算b的值,因為起點位置已經被作圓心,而a是相對於這個圓心的,所以不能帶入起點坐標進行計算

    ball.t = setInterval( function() {
        x++;//橫坐標遞增
        ball.style.left = x + centerPoint.X + "px";
        ball.style.top = a*x*x + b*x + centerPoint.Y + "px";
        if ( ball.offsetLeft >= document.getElementById("target").offsetLeft ) {
            clearInterval( timer );
        }
    }), 1);

預覽:http://htmlpreview.github.io/?https://github.com/shockw4ver/JavaScriptCases/blob/master/JSSports/定點拋物線.html

最后一個示例,緩沖運動

其實緩沖運動的原理也很簡單,其基本思路是將加速度與速度的關系轉換成每次運動的步長——比如第一次運動的步長為距離的五分之一,本次運動完成后步長又為剩下距離的五分之一,以此類推。這里的步長就相當於單位時間里運動的距離,即速度。但是在邏輯上這個方法是不可能到達終點的(芝諾悖論)。所以在步長某次計算后需要進行約束,不再讓它改變,這個值在計算機來看為1像素是再好不過了。所以當步長小於1的時候我們可以將其約束為1。

html主要代碼:

<div id="ball"></div>

css樣式:

#ball {
    height: 20px;
    width: 20px;
    background: #f00;
    position: absolute;
    top: 200px;
    left: 100px;
    border-radius: 50%;
}

JS主要代碼:

var ball = document.getElementById("ball")

var distance = 800; //設置移動的距離為800

ball.t = setInterval( function() {
    var speed = ( ( distance - ball.offsetLeft ) / 8 ) < 1 ? 1 : ( ( distance - ball.offsetLeft ) / 8 );//步長每次都為剩下距離的八分之一,當某一次步長小於1時,將其約束為1
    obj.style.left = obj.offsetLeft + speed + "px";
    if ( obj.offsetLeft == distance ) {
        clearInterval( obj.t );
    }
}, 30);

預覽:http://htmlpreview.github.io/?https://github.com/shockw4ver/JavaScriptCases/blob/master/JSSports/緩沖運動.html
PS: 這里我是將緩沖運動封裝成了一個函數,可以實現各種屬性的緩沖變換,地址為:https://github.com/shockw4ver/JavaScriptCases/blob/master/js lib/move.js
其中還需要一個getCount函數在:https://github.com/shockw4ver/JavaScriptCases/blob/master/js lib/getNodes.js

三種比較典型的運動就在這里啦!

Thanks for Read!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM