今天我們來模拟animate動畫庫實作幾個動畫效果;
首先,在html檔案建立一個div元素作為運動物體吧☺️
其次,在css檔案裡寫幾個簡單樣式吧☺️
#move {
position: absolute;
width: 30px;
height: 30px;
border-radius: 100%;
background-color: red;
}
接下來,主要的運動邏輯就在js檔案裡實作啦
- 建立一個用于實作幾種動畫效果的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;
}
};
- 定義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; // 動畫持續時間
};
- 定義啟動動畫函數
/*
啟動動畫函數
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 );
};
- 定義每一步需要做的運動
// 每一步運動要做的事
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 屬性值
};
- 通過改變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' ); // 從上到下的運動