天天看點

前端js實作動畫效果

今天我們來模拟animate動畫庫實作幾個動畫效果;

首先,在html檔案建立一個div元素作為運動物體吧☺️

其次,在css檔案裡寫幾個簡單樣式吧☺️

#move {
      position: absolute;
      width: 30px;
      height: 30px;
      border-radius: 100%;
      background-color: red;
    }
           

接下來,主要的運動邏輯就在js檔案裡實作啦

  1. 建立一個用于實作幾種動畫效果的tween對象
/* 
定義的tween内的動畫效果屬性都為緩動算法,他們都接受以下 4 個參數。
 t:動畫已消耗的時間。
 b: 小球原始位置。
 c: 小球目标位置。
 d: 動畫持續的總時間。
傳回的值則是動畫元素應該處在的目前位置
*/
var tween = { 
  linear: function( t, b, c, d ){ 
   return c*t/d + b; 
  }, 
  easeIn: function( t, b, c, d ){ 
   return c * ( t /= d ) * t + b; 
  },
  strongEaseIn: function(t, b, c, d){ 
    return c * ( t /= d ) * t * t * t * t + b; 
  }, 
  strongEaseOut: function(t, b, c, d){ 
    return c * ( ( t = t / d - 1) * t * t * t * t + 1 ) + b; 
  }, 
  sineaseIn: function( t, b, c, d ){ 
    return c * ( t /= d) * t * t + b; 
  }, 
  sineaseOut: function(t,b,c,d){ 
    return c * ( ( t = t / d - 1) * t * t + 1 ) + b; 
  } 
};
           
  1. 定義Animate動畫類
// 定義Animate類
var Animate = function( dom ){ 
  this.dom = dom; // 進行運動的 dom 節點
  this.startTime = 0; // 動畫開始時間
  this.startPos = 0; // 動畫開始時,dom 節點的位置,即 dom 的初始位置
  this.endPos = 0; // 動畫結束時,dom 節點的位置,即 dom 的目标位置
  this.propertyName = null; // dom 節點需要被改變的 css 屬性名
  this.easing = null; // 緩動算法
  this.duration = null; // 動畫持續時間
};
           
  1. 定義啟動動畫函數
/* 
啟動動畫函數
Animate.prototype.start 方法接受以下 4 個參數。
 propertyName:要改變的 CSS 屬性名,比如'left'、'top',分别表示左右移動和上下移動。
 endPos: 小球運動的目标位置。
 duration: 動畫持續時間。
 easing: 緩動算法。
*/

Animate.prototype.start = function( propertyName, endPos, duration, easing ){ 
  this.startTime = +new Date; // 動畫啟動時間
  this.startPos = this.dom.getBoundingClientRect()[ propertyName ]; // dom 節點初始位置
  this.propertyName = propertyName; // dom 節點需要被改變的 CSS 屬性名
  this.endPos = endPos; // dom 節點目标位置
  this.duration = duration; // 動畫持續事件
  this.easing = tween[ easing ]; // 緩動算法
  var self = this; 
  var timeId = setInterval(function(){ // 啟動定時器,開始執行動畫
	  if ( self.step() === false ){ // 如果動畫已結束,則清除定時器
		  clearInterval( timeId );
	  } 
  }, 19 ); 
};
           
  1. 定義每一步需要做的運動
// 每一步運動要做的事
Animate.prototype.step = function(){ 
  var t = +new Date; // 取得目前時間
  if ( t >= this.startTime + this.duration ){ // 目前時間>起始時間+持續時間時,停止運動 
  this.update( this.endPos ); // 更新小球的 CSS 屬性值
  return false; 
  } 
  var pos = this.easing( t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration ); 
  // pos 為小球目前位置
  this.update( pos ); // 更新小球的 CSS 屬性值
 };
           
  1. 通過改變css屬性更新運動物體的位置
//  更新運動物體 CSS 屬性值
 Animate.prototype.update = function( pos ){ 
  this.dom.style[ this.propertyName ] = pos + 'px'; 
 };
           

大功告成,下面可以驗證運動效果啦😆

//  測試運動效果:
 var moveEle = document.getElementById( 'move' ); 
 var animate = new Animate( moveEle ); 
 animate.start( 'left', 500, 1000, 'strongEaseOut' ); // 從左到右的運動
//  animate.start( 'top', 1500, 500, 'strongEaseIn' ); // 從上到下的運動