Home  >  Article  >  Web Front-end  >  Code example of parabolic motion for elastic potential energy animation in JavaScript

Code example of parabolic motion for elastic potential energy animation in JavaScript

黄舟
黄舟Original
2017-07-27 16:30:591695browse

Parabolic movement is: when the drag ends, we make the current element move horizontally + vertically at the same time

Under the same movement distance, we move the mouse If the speed is fast, the move method is triggered less often. On the contrary, if the moving speed is slow, the move method is triggered more times ->The browser triggers each move behavior by a minimum time

Through observation, we discovered one thing: the speed at which our box moves in the horizontal direction when dragging ends is not necessarily related to the distance moved, nor is it necessarily related to the speed at which dragging begins. It is only related to The speed of the mouse at the moment when it is about to be released for the last time is related. If the mouse moves fast at the last moment, the distance and speed of our horizontal movement will also be relatively large. ->Get the speed when the mouse is about to be released for the last time.

In the JS box model, offsetLeft is to get the left offset of the current element. The obtained value will never appear in decimals. It will calculate the real left value according to the decimal point. Rounding calculation

##The specific code is as follows:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding:0;
        }
        html,body{
            width:100%;
            height:100%;
        }
        #box{
            position:absolute;
            top:50%;
            left:50%;
            width:200px;
            height:200px;
            background:#ff6600;
            margin:-100px 0 0 -100px;
            cursor:move;
            /*
                不知道宽高的情况下的居中
            position:absolute;
            top:0;
            left:0;
            right:0;
            bottom:0;
            margin:auto;
            */    
        }
    </style>
</head>
<body>
    <div id=&#39;box&#39;>
        
    </div>
    <script>
        //JS实现让当前的元素在屏幕居中的位置
        var box = document.getElementById(&#39;box&#39;);
        // box.style.top = ((document.documentElement.clientHeight || document.body.clientHeight)-box.offsetHeight)/2 + "px";

        // box.style.left = ((document.documentElement.clientWidth || document.body.clientWidth)-box.offsetWidth)/2 + "px";
        //拖拽的原理
        /*
            当鼠标在盒子上按下的时候,我们开始拖拽(给盒子绑定onmousemove和onmouseup),当鼠标移动的时候,我们计算盒子的最新位置
            当鼠标抬起的时候说明拖拽结束了,我们的move和up就没用了,我们再把这两个方法移除
        */
        box.onmousedown = down;
        function down(e){
            e = e || window.event;
            //记录开始位置的信息
            this["strX"] = e.clientX;
            this["strY"] = e.clientY;
            this["strL"] = parseFloat(this.style.left);
            this["strT"] = parseFloat(this.style.top);
            //给元素绑定移动和抬起的事件
            if(this.setCapture){
                this.setCapture()//把当前的鼠标和this绑定在一起
                this.onmousemove = move;
                this.onmouseup= up;
            }else{
                var _this = this;
                document.onmousemove = function(e){
                    // move(e)//这个里面的this是window
                    move.call(_this,e);
                }
                    ;
                document.onmouseup= function(e){
                    up.call(_this,e);
                };
            }
            //当盒子运动中我们想要执行下一次拖拽,我们按下鼠标,但是由于盒子还是运动着呢,导致鼠标抓不住盒子->在按下的同时我们应该停止盒子的运动
            window.clearInterval(this.flyTimer);
            window.clearInterval(this.dropTimer);
            
        }
        function move(e){
            e = e || window.event;
            var curL = (e.clientX-this["strX"])+this["strL"];
            var curT = (e.clientY-this["strY"])+this["strT"];
            //边界判断
            var minL = 0,minT = 0,maxL = (document.documentElement.clientWidth || document.body.clientWidth) - this.offsetWidth,maxT = (document.documentElement.clientHeight || document.body.clientHeight) - this.offsetHeight;
            curL = curL < minL ? minL :(curL > maxL ? maxL : curL);
            curT = curT < minT ? minT :(curT > maxT ? maxT : curT)
            this.style.left = curL + "px";
            this.style.top = curT + "px";

            //计算我们水平方向移动的速度
            /*
                在浏览器最小反应时间内触发一次move,我们都记录一下当前盒子的位置,让当前的位置-上一次记录的位置=当前最后一次的偏移
            */
            if(!this.pre){
                this.pre = this.offsetLeft;
            }else{
                this.speedFly = this.offsetLeft - this.pre;
                this.pre = this.offsetLeft;
            }
        }
        function up(e){
            if(this.releaseCapture){
                this.releaseCapture();//把当前的鼠标和盒子解除绑定
                this.onmousemove = null;
                this.onmouseup= null;
            }else{
                document.onmousemove = null;
                document.onmouseup= null;
                //这样绑定的话,move和up绑定的this都是document
            }
            //当鼠标离开结束拖拽的时候,我们开始进行水平方向的动画运动
            fly.call(this);
            //当鼠标离开结束拖拽的时候,我们开始进行垂直方向的动画运动
            drop.call(this);
            
        }
        //当鼠标移动过快的时候,我们的鼠标会脱离盒子,导致盒子的mousemove和mouseup事件都移除不到->"鼠标焦点丢失"
        //在IE和火狐浏览器中,我们用一个方法把盒子和鼠标绑定在一起即可。
        //鼠标再快也跑不出去文档:我们把mousemove和mouseup绑定给document
        
        
        function fly(){
            //this->当前要操作的盒子
            var _this = this;
            _this.flyTimer = window.setInterval(function(){
                //我们运动的速度是一直在减慢的,一直到停止("指数衰减运动")
                //this->window
                //盒子停止运动,清除定时器:利用offsetLeft获取的值不会出现小数,对小数部分进行了四舍五入,所以我们加上或者减去一个小于0.5的速度值,其实对于盒子本身的位置并没有发生实质的改变,我们认为此阶段的盒子就停止运动了。

                if(Math.abs(_this.speedFly)<0.5){
                    window.clearInterval(_this.flyTimer);
                    return;
                }
                _this.speedFly*=0.98;
                var curL = _this.offsetLeft + _this.speedFly;
                var minL = 0,maxL = (document.documentElement.clientWidth || document.body.clientWidth) - _this.offsetWidth;
                if(curL>=maxL){
                    _this.style.left = maxL + "px";
                    _this.speedFly*=-1;
                }else if(curL<=minL){
                    _this.style.left = minL + "px";
                    _this.speedFly*=-1;
                }else{
                    _this.style.left = curL;
                }
            },10)
            

        }

        function drop(){
            var _this = this;
            _this.dragFlag = 0;
            _this.dropTimer = window.setInterval(function(){
                if(_this.dragFlag>1){//到底的时候dragFlag就大于1了
                    window.clearInterval(_this.dropTimer);
                    return;
                }
                _this.dropSpeed = !_this.dropSpeed ? 9.8 : _this.dropSpeed + 9.8;
                //衰减
                _this.dropSpeed*=0.98;
                var curT = _this.offsetTop + _this.dropSpeed;
                var maxT = (document.documentElement.clientHeight || document.body.clientHeight) - _this.offsetHeight;
                if(curT >= maxT){// 到底了
                    _this.style.top = maxT + "px";
                    _this.dropSpeed*=-1;
                    _this.dragFlag++;
                }else{
                    _this.style.top = curT + "px";
                    _this.dragFlag = 0;
                }
            })
            
        }
    </script>
</body>
</html>


The above is the detailed content of Code example of parabolic motion for elastic potential energy animation in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn