基於svg mask實現的tab切換效果

效果

tab切換效果

第一次看到這個效果是在阿里媽媽MUX的博客:UI動效—細微交互,極致體驗,裏面蒐集的一些微交互都讓人眼前一亮,恰好自己最近要做一個按鈕組,就參考了裏面Sergey Valiukh的一個設計。

源碼

和上兩篇博客一樣,相對簡單,爲了節省你的閱讀時間,直接上源碼:

上兩篇博客:
D3.js SVG繪圖實踐:趨勢縮略圖
D3.js SVG繪圖實踐:波浪動畫

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>transition-tabs</title>
    <link rel="stylesheet" href="transition-tabs.css">
  </head>
  <body>
    <div class="transition-tabs">
      <svg width="100%" height="100%">
        <defs>
          <mask id="mask">
            <rect x="0" y="0" width="33.33%" height="100%" fill="white"  />
          </mask>
        </defs>
        <!-- 背景 -->
        <rect x="0" y="0" width="100%" height="100%" fill="#5d5070"/>
        <!-- 頂層遮罩 -->
        <g mask="url(#mask)">
          <rect x="0" y="0" width="33.33%" height="100%" fill="#75adcc"/>
          <rect x="33.33%" y="0" width="33.33%" height="100%" fill="#f3b16d"/>
          <rect x="66.66%" y="0" width="33.33%" height="100%" fill="#e55b56"/>
        </g>
      </svg>
      <!-- 底層的文字,點擊文字切換動畫 -->
      <div>
        <span>前85%</span>
        <span>85%~95%</span>
        <span>後5%</span>
      </div>
    </div>
    <script src="transition-tabs.js"></script>
  </body>
</html>
.transition-tabs {
  position: relative;
  width: 300px;
  height: 30px;
}
.transition-tabs div{
  position: absolute;
  width: 100%;
  left: 0;
  top: 0;
  display: flex;
  text-align: center;
}
.transition-tabs div span{
  flex: 1;
  color: white;
  line-height: 30px;
  cursor: pointer;
}
.transition-tabs #mask rect {
  position: absolute;
  transition: transform 0.4s ease-in-out 0.1s;
  transform: translate3d(0,0,0);
}
;(function(){
  var mask = document.querySelector("#mask rect");

  var handleClick = function(e){
    console.log("click",e);
  };

  //事件代理
  document.querySelector(".transition-tabs div").addEventListener("click", function(e){
    var target = e.target;
    if (target.nodeName.toLowerCase() == "span") {
      var end = target.offsetLeft;
      mask.style.transform = "translateX(" + end + "px)";
      if (handleClick) {
        handleClick(e);        
      }
    }
  });
})();

爲了避免大家複製粘貼的麻煩,已將該項目上傳到github,隨意使用:

transition-tabs

實現

①mask(遮罩)

之前沒接觸過的知識點只有一個,就是svg的mask,作用和css中的mask一樣,使用mask層來控制顯示哪一部分,區別在於svg mask顯示mask區域爲白色的部分,css mask顯示mask區域爲黑色的部分。

盜圖一張:
mask作用

但是css中的mask兼容性可謂慘不忍睹:
css mask兼容性

於是使用了SVG mask。

②移動遮罩

移動遮罩就使用了css中簡單的translate3D(),比較簡單,就不說了,在綁定點擊事件的時候用了事件代理的方法,讓父級捕獲並處理三個子級(這裏指span)的點擊事件,既避免全局事件代理可能帶來的性能問題,又減少事件綁定次數。

總結

一個比較簡單的東西好像沒有必要寫,當做每週的一個記錄好了。

昨天面試官問了一些移動端的事件,感覺自己瞭解得不多,還是要穩紮穩打,擴大知識面廣度同時確保深度。這周正好發燒,剛退燒,休息之餘打算看看zepto的源碼,向優秀的人看齊,你纔會更加優秀,加油。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章