>  기사  >  웹 프론트엔드  >  JavaScript의 탄성 위치 에너지 애니메이션을 위한 포물선 운동의 코드 예

JavaScript의 탄성 위치 에너지 애니메이션을 위한 포물선 운동의 코드 예

黄舟
黄舟원래의
2017-07-27 16:30:591745검색

포물선 운동은 드래그가 끝나면 현재 요소를 수평 + 수직으로 동시에 이동하게 합니다.

동일한 이동 거리에서 마우스는 더 빠르게 움직이고 반대로 이동 방법은 덜 자주 실행됩니다. 움직임이 느릴수록 이동 메서드가 더 많이 트리거됩니다. -> 브라우저는 최소 시간만큼 각 이동 동작을 트리거합니다.

관찰을 통해 우리는 한 가지 사실을 발견했습니다: 상자가 수평 방향으로 끝납니다. 드래그할 때의 이동 속도 반드시 이동한 거리와 관련이 있는 것은 아니며 드래그를 시작하는 속도와 반드시 관련이 있는 것도 아닙니다. 마우스를 마지막으로 놓으려고 하는 순간의 속도에만 관련됩니다. 마지막 순간의 속도는 반드시 관련이 있는 것은 아닙니다. 빠르게 이동하면 수평 이동의 거리와 속도도 상대적으로 커집니다. ->마우스를 마지막으로 놓을 때의 속도를 구합니다.

JS 박스 모델에서 offsetLeft는 현재 요소의 왼쪽 오프셋을 가져오는 것입니다. 얻은 값은 소수점 반올림에 따라 실제 왼쪽 값을 계산합니다.

구체적인 코드는 다음과 같습니다.

<!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>


위 내용은 JavaScript의 탄성 위치 에너지 애니메이션을 위한 포물선 운동의 코드 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.