動畫 勻速動畫

指定步長的動畫

首先獲取動畫距離,使用動畫終點 - 動畫起點;而後使用一個定時器,每隔必定毫秒數獲取當前元素的當前位置累加上步長,再把累加後的位置設置回去。在累加以前判斷一下,當前位置是否已經到達了終點,若是到達終點清除定時器,並終止後面的操做。css

指定時長的動畫

時間時固定的,路程是固定的,因此指定時間的動畫關鍵在於求得速度,即每次定時器執行時元素改變的距離。node

回到頂部

  1. 將頁面的scrollTop 設爲 0
  2. 緩慢回去 - 指定時間
  3. 緩慢回去 - 指定步長
  4. 圖片漸現
// 1. 導入工具方法
const {css} = window.utils;

// 2. 獲取元素
let img = document.querySelector('.img-con > img');

// 3. 設定定時器啓動動畫
let timer = setInterval(() => {
  // 3.1 獲取當前元素的透明度
  let op = +css(img, 'opacity');
  // 3.2 給透明度累加,並判斷累加後的值
  op += 0.01;
  if (op >= 1) {
    clearInterval(timer);
    op = 1;
  }
  // 3.3 把累加後的值設置回去
  css(img, 'opacity', op);
}, 16);
複製代碼
  1. 勻速動畫 速度是必定的,時間時固定的,因此最爲關鍵的是求出路程,而後再求出速度
  2. 勻速運動中某一時刻的位置計算
function linear(curTime, begin, change, duration) {
  // 計算勻速運動時,元素某一時刻的位置
  return (change / duration) * curTime + begin;
}
複製代碼
  1. 多方向的勻速動畫即元素的多個 js 屬性同時變化

封裝動畫庫

// Effect 運動方式
const Effect = {
  Linear: function (curTime, begin, change, duration) {
    return change / duration * curTime + begin;
  }
};

function animate({ele, target = {}, duration = 2000, after}) {
  // 1. 參數校驗
  if (!ele || ele.nodeType !== 1) {
    throw TypeError('ele is not a DOM ELEMENT')
  }

  // 2. 準備動畫須要的參數
  const {css} = window.utils;

  // 2.1 根據 target 中傳入的屬性,計算這些屬性的起始位置以及這些屬性的運動距離
  let begin = {};
  let change = {};

  // 遍歷 target 對象
  for (let k in target) {
    if (target.hasOwnProperty(k)) {
      begin[k] = css(ele, k); // 用 css 方法獲取元素的起始位置
      change[k] = target[k] - begin[k]; // 獲取元素運動的路程
    }
  }

  // 2.2 記錄當前時間
  let time = 0;

  // 2.3 設置 interval
  let interval = 16;

  // 3. 建立動畫定時器
  ele.timer && clearInterval(ele.timer); // 每次開始新的動畫時中止上一次的動畫
  ele.timer = setInterval(() => {
    time += interval;

    if (time > duration) {
      css(ele, target);
      clearInterval(ele.timer);
      // 調用鉤子函數
      if (typeof after === 'function') {
        after.call(ele); // 讓 after 執行,而且把 after 中的 this 修改爲 ele
      }
      return;
    }
    let curState = {};
    // 計算當前元素的位置
    for (let k in target) {
      if (target.hasOwnProperty(k)) {
        curState[k] = Effect.Linear(time, begin[k], change[k], duration)
      }
    }
    // 把當前元素的相應的屬性設置爲當前狀態
    css(ele, curState);
  }, interval)

}
複製代碼
相關文章
相關標籤/搜索