用js實現簡單的拋物線運動


前言

老早就看過一些購物車的拋物線效果,也想自己湊熱鬧動手來實現一遍。

然后(lll¬ω¬) 書到用時方恨少,發現高中學到物理啊、數學啊,都忘光了,拋物線公式都忘了0 0。

順手百度一波,從百度可知:y=ax^2+bx+c

ps:順路吐槽一下,以前學習是為了應付考試,該忘的都忘了,根本不知道怎么運用到實際生活中,沒有學以致用

實現

吐槽完了,現在我們准備看看怎么實現我們的拋物線動畫啦

首先從公式和我們頁面的dom可知,坐標點(x,y)是已知的,參數a、b、c是未知

因為坐標系是由我們設定,所以我們可以假設我們的初始點為(0,0) O(∩_∩)O這樣也是方便我們后面的計算

代入公式可知,c = 0 則剩下的問題就是求a、b了

假設a=0.001 => 實際指焦點到准線的距離,可以抽象成曲率,這里模擬扔物體的拋物線,因此是開口向下的

則 b = (y - 0.001 * x * x) / x , 那么b也是可以算出來的了,知道了這些,終於,我們可以寫代碼了 O(∩_∩)O

完整代碼:

<!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 {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            overflow: hidden;
            position: absolute;
        }

        #div1 {
            background: red;
            top: 10%;
            left: 10%;
        }

        #div2 {
            background: #ccc;
            top: 50%;
            right: 50%;
        }
    </style>
</head>

<body>

    <div id="div1"></div>
    <div id="div2"></div>

    <button id="btn" onclick="start()">拋物線</button>
    <script>
        // 拋物線計算公式 y = a*x*x + b*x + c
        // 坐標點x、y是已知的,a、b、c是未知的

        // 獲取初始元素
        let oDiv1 = document.getElementById("div1")

        // 獲取目標元素
        let oDiv2 = document.getElementById("div2")

        // 獲取初始元素的位置
        let elX = oDiv1.getBoundingClientRect().left
        let elY = oDiv1.getBoundingClientRect().top

        // 獲取初始元素到目標元素的偏移總量
        let diffX = oDiv2.getBoundingClientRect().left - oDiv1.getBoundingClientRect().left
        let diffY = oDiv2.getBoundingClientRect().top - oDiv1.getBoundingClientRect().top

        // 假設(elX,elY)為(0,0),則c = 0,求a、b
        // 設a=0.001 => 實際指焦點到准線的距離,可以抽象成曲率,這里模擬扔物體的拋物線,因此是開口向下的
        let a = 0.001

        // 則 b = (y - a*x*x) / x
        let b = (diffY - a * diffX * diffX) / diffX

        // 定義一個定時器,用來執行拋物線動畫
        let timer = null;

        // 執行的時間
        let duration = 1500

        function start() {
            // 執行的開始時間
            beginTime = new Date()
            // 結束的時間
            endTime = +beginTime + duration
            // 定時器,執行拋物線動畫
            timer = setInterval(() => {
                let now = new Date()
                step(now);
            }, 13);
        }

        // 拋物線動畫的方法
        function step(now) {
            let x, y;
            if (now > endTime) {
                // 運行結束
                x = diffX;
                y = diffY;
                clearInterval(timer);
            } else {
                // 計算每一步的X軸的位置
                x = diffX * ((now - beginTime) / duration);
                // 則每一步的Y軸的位置y = a*x*x + b*x + c;   c==0;
                y = a * x * x + b * x;
            }
            oDiv1.style.cssText = `position:absolute;left:${elX + x}px;top:${elY + y}px`
        }
    </script>

</body>

</html>

最后,感謝各位觀眾老爺觀看


免責聲明!

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



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