教你用原生CSS寫炫酷頁面切換效果,跟第三方組件說拜拜


因為項目需要,別人想讓我給他寫一個個人博客,並且給了我一個其他人的網頁,可以點此查看。有的同學可能說了,第三方博客框架這么多,為什么還要去手寫的,你說這個有可能是沒有看到打開這個博客。

樣式介紹

給大家看一下這個網頁的大體樣式。

這個界面可以說是非常漂亮,整體也是一個響應式布局,總體來說還算不錯。但是拋開頁面設計,這個網站有一個致命的缺點,就是沒有做懶加載,這么多頁面其實就是一個HTML文件,所有的資源圖片以及文字信息等全部是一次性加載,所以你想打開這個界面還是比較困難的,需要等待一些時間。

我們這次只看設計。其實用Vue的朋友們應該都聽過element-ui這個組件庫,它里面有一個抽屜組件可以用。其實用這種現成的組件的局限性大家都很清楚,雖然說開發很快,但是定制化有很多限制,向上面GIF圖中的效果他就不能很好的實現。於是本着學習的態度我們來實現一下這個樣式。

實現方法

話不多說,我們先來看一下實現效果

我們大致實現了想要實現的效果:

  • 點擊不同標簽頁出現相應界面
  • 切換動畫
  • 點擊蒙版收回頂層標簽頁

切換動畫

動畫的實現方法有很多,在CSS里面寫動畫的話我比較常用keyframes,但是在這里我是用js來控制動畫,沒有使用css動畫屬性。js實現動畫的話大家思考一下連環畫的生成原理,其實就是在很短的事件里面對圖片的頻繁移動,只要移動速度合適,我們的眼睛就會認為我們看到了一個移動的物體。

我js實現動畫的原理和此類似,設定一個延時與起始位置,讓他在規定時間內按照liner均勻移動,當然你也可以不使用liner,比如說X2,這些也都是可以的。

關於實現方法,我是寫了一個animation類,這個類包括延時、函數(liner或者其他漸變函數)、completed等,可以很好地進行動畫生成與控制。下面來看一下這段代碼

class Animator {
  // 構造函數
  constructor() {
    this.durationTime = 0;
    this.easingFn = k => k;
    this.eventHandlers = new Map();
  }
  // 動畫移動速度所用的函數
  easing(fn) {
    if (typeof fn !== "function") {
      throw new Error("Easing must be a function, such as k => k");
    }
    this.easingFn = fn;
    return this;
  }
  // 動畫時間
  duration(time) {
    if (typeof time !== "number") {
      throw new Error("Duration must be a number");
    }
    this.durationTime = time;
    return this;
  }
  // 響應函數
  on(type, handler) {
    if (typeof handler !== "function") {
      throw new Error("Handler must be a function");
    }
    this.eventHandlers.set(type, handler);
    return this;
  }
  // 動畫生成
  animate() {
    const duration = this.durationTime;
    const easing = this.easingFn;
    const update = this.eventHandlers.get("update") || (t => t);
    const complete = this.eventHandlers.get("complete") || (() => {});
    let timer = null;
    const startTime = +new Date();
    function step() {
      const percent = Math.min(1, (+new Date() - startTime) / duration);
      if (percent < 1) {
        update(easing(percent));
        timer = requestAnimationFrame(step);
      } else {
        cancelAnimationFrame(timer);
        update(easing(1));
        complete();
      }
    }
    timer = requestAnimationFrame(step);
  }
}
/*
* 這里是專門寫了一個產生動畫的函數
* 傳參: start:Number, step:Number, el:object(元素對象)
* 傳入這些參數之后就可以產生相應的動畫效果
*/
var move = function(start, step, el) {
  new Animator()
    .duration(200)
    .easing(k => k)
    .on("update", t => {
      el.style.right = String(start + t * step) + "%";
    })
    .animate();
};

網頁布局

其實像這種抽屜式的網頁布局大家應該都不陌生,大概就是設置positionabsolute,然后再使用left或者right屬性進行布局,我在文章下面會給出全部代碼的下載鏈接,大家如果感興趣可以下載來看一下。

點擊邏輯

通過我前面的介紹,大家應該是可以知道這個demo是可以通過按鈕點擊觸發,也是可以通過點擊蒙版來觸發的,當我的鼠標移到蒙版的時候鼠標會改變一個樣式,這個只要設置一個屬性就可以啦

.overlay {
  cursor: url("你的圖標url"), pointer;
}

具體的邏輯大家可以參照這個思維導圖

其實當時這個邏輯搞了比較長時間,大家應該可以想到實現多個標簽頁的點擊應該是使用棧來實現,始終把顯示出來的抽屜頁放在最頂層,這樣也方便我們進行后續操作。

網頁源碼

需要源碼的朋友可以點此下載😜

小結

在剛開始學web前端開發的時候,看到一些特別的網站覺得很炫酷,當時的第一想法是看看GitHub上有沒有現成的組件庫可以給我用,所以也造就了我原生css學的不是很扎實。但是到現在來講,隨着工作的需要,為了有更好的突破還是得努力學習原生web。一些框架和組件都是基於原生的,只有這些學扎實了之后才能更好地認識和使用這些現成的輪子。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM