放物線運動とは: ドラッグが終了すると、現在の要素が水平方向と垂直方向に同時に移動します
同じ移動距離では、マウスの移動が速くなり、逆に、move メソッドがトリガーされる頻度が低くなります。動きが遅いほど、移動メソッドがトリガーされる回数が多くなります -> ブラウザーは各移動動作を最小限の時間でトリガーします
観察を通じて、私たちは 1 つのことを発見しました: ボックスは水平方向に終わっています ドラッグ時の移動速度必ずしも移動距離に関係するわけではなく、ドラッグを開始する速度にも必ずしも関係しません。最後にマウスを放そうとする瞬間のマウスの速度にのみ関係します。最後の瞬間の速度は必ずしも関係ありません。速く移動すると、水平移動の距離と速度も比較的大きくなります。 ->最後にマウスを放そうとするときの速度を取得します。
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='box'> </div> <script> //JS实现让当前的元素在屏幕居中的位置 var box = document.getElementById('box'); // 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 中国語 Web サイトの他の関連記事を参照してください。