1. 程式人生 > 實用技巧 >前端學習筆記JavaScript - 動畫增強封裝

前端學習筆記JavaScript - 動畫增強封裝

動畫封裝

  1. 增加多條動畫同時執行
  2. 將前進後退/放大縮小方法合併
  3. 增加動畫執行完成後回撥方法
  4. 將程式碼封裝到動畫類中

程式碼

  • html程式碼
<button class="begin500">開始到500</button>
<button class="begin200">開始到200</button>
<button class="end">結束</button>
<div class="box"></div>
<div class="blue-box"></div>
<div class="red-box"></div>
  • css程式碼
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .box {
      width: 100px;
      height: 100px;
      background-color: #E83733;
    }

    .blue-box,.red-box {
      height: 10px;
    }

    .blue-box {
      width: 500px;
      background-color: blue;
    }

    .red-box {
      width: 200px;
      background-color: red;
    }
  </style>
  • 引入js檔案
  <script src="js/animatin.js"></script>
  • javascript程式碼
<script>
  // - 獲取所有需要操作的元素
  let oBox = document.querySelector(".box");
  let begin500Btn = document.querySelector(".begin500");
  let begin200Btn = document.querySelector(".begin200");
  let endBtn = document.querySelector(".end");
  begin500Btn.onclick = function () {
    let obj = {
      "marginLeft":500,
      "width":200
    }
    easeAnimation(oBox,obj,function () {
      alert("動畫執行完成");
    })
  }
  begin200Btn.onclick = function () {
    let obj = {
      "marginLeft":200
    }
    easeAnimation(oBox,obj,function () {
      alert("動畫執行完成");
    })
  }

  endBtn.onclick = function () {

    clearInterval(oBox.timer)
  }
</script>
  • 動畫類
(
  function () {


    // - 勻速動畫
    /* ele 需要動畫的元素
     * obj 需要動畫的屬性
     * step 每次移動的距離/大小
     * fn 動畫執行完成回撥方法
     */
    function linearAnimation(ele,obj,step,fn) {
      // - 清空定時器
      clearInterval(ele.timer);
      ele.timer = setInterval(function () {
        let flag = true;
        for (let key in obj) {
          // - 獲取初始位置
          let begin = parseInt(getComputedStyle(ele)[key]);
          step = begin - obj[key] > 0 ? -13:13;
          begin += step;

          if (Math.abs(begin - obj[key]) > Math.abs(step)){
            flag = false;
          }else
          {
            begin = obj[key];
          }
          ele.style[key] = begin+"px";
        }
        console.log(flag);
        if (flag) {
          clearInterval(ele.timer);
          fn && fn();
        }
      },100)
    }


    // - 緩動動畫
    /* ele 需要動畫的元素
     * obj 需要動畫的屬性
     * fn 動畫執行完成回撥方法
     */
    function easeAnimation(ele,obj,fn) {
      // - 每次啟動定時器前先移出定時器,防止定時器多次執行
      clearInterval(ele.timer);
      // - 開啟定時器
      ele.timer = setInterval(function () {
        // - 在計時器定義一個flag來記錄是否已經完成動畫
        let flag = true;
        // - 遍歷obj中的值,執行動畫
        for (let key in obj) {
          // - 起始位置
          let begin = parseInt(getComputedStyle(ele)[key]);
          // - 此處步數是可變的,所以放在定時器裡面
          // - 緩動動畫公式 (結束位置 - 起始位置)* 緩動係數(0~1)
          let step = (obj[key] - begin) * 0.3;
          // - 使用當前起始位置 + 每次移動距離 = 這次移動的距離
          begin += step;
          if (Math.abs(Math.floor(step)) > 1){
            // - 動畫未完成
            flag = false;
          }else
          {
            // - 賦值到起始位置
            begin = obj[key];
          }
          // - 移動位置
          ele.style[key] = begin+"px";
        }
        console.log(flag);
        if (flag){
          // - 停止計時器
          clearInterval(ele.timer);
          // - 方法判空,如果有fn不為空才執行方法
          fn && fn();
        }
      },100)
    }

    window.linearAnimation = linearAnimation;
    window.easeAnimation   = easeAnimation;

  }
)()