中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

js彈性勢能動畫之拋物線運動實例詳解

發布時間:2020-08-25 05:33:34 來源:腳本之家 閱讀:178 作者:diasa 欄目:web開發

拋物線運動就是:當拖拽結束的時候,我們讓當前的元素同時水平運動+垂直運動

在同樣的移動距離下,我們鼠標移動的速度快,move方法觸發的次數少,相反移動的速度慢,move方法觸發的次數就多->瀏覽器對于每一次的move行為的觸發都是由一個最小時間的。

通過觀察,我們發現一個事情:水平方向我們盒子在結束拖拽的時候移動的速度和移動的距離沒有必然的聯系,和開始拖拽的速度也沒有必然的聯系,只和最后一次即將松開的那一瞬間鼠標的速度是有關系的,最后瞬間鼠標如果移動的快,我們水平運動的距離和速度也是比較大的。->獲取鼠標最后一次即將松開時候的速度。

在JS盒子模型中,offsetLeft是獲取當前元素的左偏移,獲取到的值永遠不會出現小數,  他會把真實的left值按照小數點的四舍五入進行計算

具體代碼如下:

<!DOCTYPE html>
<html lang="en">
<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>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

襄垣县| 四子王旗| 黄骅市| 德兴市| 兴宁市| 麦盖提县| 安国市| 攀枝花市| 东台市| 星子县| 额敏县| 三原县| 巫山县| 安国市| 安丘市| 邻水| 泰安市| 犍为县| 当阳市| 内江市| 平原县| 紫云| 内丘县| 土默特右旗| 新巴尔虎右旗| 天柱县| 苗栗市| 关岭| 车致| 固原市| 金堂县| 三亚市| 汉川市| 新建县| 康平县| 博野县| 钦州市| 准格尔旗| 延长县| 永丰县| 托克逊县|