高效能 CSS 動畫示例

這篇文章將說明如何在 CodePen 上發現一些熱門動畫。這些動畫全都使用本節其他文章所討論的高效能技術。

請參閱為什麼某些動畫緩慢?請參閱這些建議背後的理論,以及動畫指南中的實用提示。

精靈載入動畫

View Wizard 載入 CodePen 的動畫

此載入動畫完全是以 CSS 建構而成。圖片和所有動畫都是在 CSS 和 HTML 中建立,沒有任何圖片或 JavaScript。歡迎參閱 Chrome 開發人員工具,瞭解這項工具的開發方式和成效。

使用 Chrome 開發人員工具檢查動畫

播放動畫時,在 Chrome 開發人員工具中開啟「效能」分頁,並錄製動畫幾秒鐘。 從摘要中,您應該會看到瀏覽器在執行此動畫時,並未執行任何版面配置或小畫作業。

開發人員工具中的摘要
剖析精靈動畫後的摘要。

如果想瞭解這個動畫如何在不造成版面配置和繪製的情況下達成,請查看 Chrome 開發人員工具中所有移動的元素。您可以使用動畫面板找出各種動畫元素,按一下任何元素即可在 DOM 中醒目顯示該元素。

「Animations」面板顯示動畫的各個部分。
在 Chrome 開發人員工具動畫面板中查看及選取項目。

舉例來說,您可以選取三角形,觀察元素方塊在飛行過程中如何轉換,在旋轉後返回起始位置。

這部影片說明如何在 Chrome 開發人員工具中追蹤三角形的路徑。

在仍然選取元素的情況下,查看「樣式」面板。從這裡可以看到 CSS 繪製三角形的形狀,以及目前使用的動畫。

運作方式

三角形是使用 ::after 虛擬元素建立而成,並使用邊框建立形狀,藉此新增生成內容。

.triangle {
    position: absolute;
    bottom: -62px;
    left: -10px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
}

.triangle::after {
    content: "";
    position: absolute;
    top: 0;
    right: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 28px 48px 28px;
    border-color: transparent transparent #89beb3 transparent;
}

加入動畫時,請使用以下一行 CSS

animation: path_triangle 10s ease-in-out infinite;

繼續使用 Chrome 開發人員工具後,只要向下捲動「樣式」面板,就能找到主要畫面格。 在這裡,您會發現使用 transform 變更元素位置並旋轉元素,即可建立動畫。transform 屬性是動畫指南中所述的其中一種屬性,不會導致瀏覽器執行版面配置或繪製作業 (這是動畫緩慢的主要原因)。

@keyframes path_triangle {
  0% {
    transform: translateY(0);
  }
  10% {
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
  }
  55% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  58% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  63% {
    transform: rotate(-360deg);
  }
}

此動畫中每個不同的移動部分使用類似的技術。如此一來,便可產生十分複雜的動畫,並確保動畫流暢地播放。

閃爍圓形

查看 CodePen 的 Pulsating Circle

這類動畫有時可用來吸引使用者註意網頁上的項目。如要瞭解動畫,您可以使用 Firefox 開發人員工具。

使用 Firefox 開發人員工具檢查動畫

播放動畫時,在 Firefox 開發人員工具中開啟「效能」分頁,並錄製動畫幾秒鐘。 停止記錄,您應該在刊登序列中會看到「Recalculate Style」(重新計算樣式) 項目隨即會出現。您現在知道這個動畫不會重新計算樣式,因此也因此瞭解版面配置和繪製作業。

Firefox Waterfall 中的動畫細節
Firefox 開發人員工具瀑布圖。

保持開啟 Firefox 開發人員工具,檢查圓圈,看看動畫的運作方式。 具有 pulsating-circle 類別的 <div> 會標示圓形的位置,但不會繪製圓形本身。

.pulsating-circle {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 30px;
    height: 30px;
}

您可以使用 ::before::after 虛擬元素來完成可見的圓形和動畫。

::before 元素會使用名為 pulse-ring 的動畫 (為 transform: scaleopacity 建立動畫),從白色圓圈外延伸。

.pulsating-circle::before {
    content: '';
    position: relative;
    display: block;
    width: 300%;
    height: 300%;
    box-sizing: border-box;
    margin-left: -100%;
    margin-top: -100%;
    border-radius: 45px;
    background-color: #01a4e9;
    animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%, 100% {
    opacity: 0;
  }
}

另一個查看動畫屬性的方法,是在 Firefox 開發人員工具中選取「Animations」面板。 你會看到以視覺化方式呈現使用的動畫,以及正在播放的動畫屬性。

如果在選取虛擬元素前選取「::」,就可以查看哪些屬性正在播放動畫。

使用 ::after 虛擬元素建立白色圓圈本身並產生動畫效果。動畫 pulse-dot 使用 transform: scale,在動畫播放期間成長及縮小圓點。

.pulsating-circle::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 15px;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
  animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

這類動畫可用於應用程式中的不同位置,因此這些微小的調整不會影響應用程式的整體效能。

純粹 CSS 3D 全景

在 CodePen 上查看 Pure CSS 3D 全景

無論動畫運用到以上範例提到的技巧,這個動畫似乎都變得非常複雜。複雜程度源自於為大量元素建立動畫效果。

開啟 Chrome 開發人員工具,並選取類別為 plane 的其中一個元素。 球體是由一組旋轉的飛機和輪輻組成,

飛機似乎正在旋轉。

這些飛機和輪輻位於包裝函式 <div> 內,也就是使用 transform: rotate3d 旋轉的元素。

.sphere-wrapper {
  transform-style: preserve-3d;
  width: 300px;
  height: 300px;
  position: relative;
  animation: rotate3d 10s linear infinite;
}

@keyframes rotate3d {
  0% {
    transform: rotate3d(1, 1, 1, 0deg);
  }
  25% {
    transform: rotate3d(1, 1, 1, 90deg);
  }
  50% {
    transform: rotate3d(1, 1, 1, 180deg);
  }
  75% {
    transform: rotate3d(1, 1, 1, 270deg);
  }
  100% {
    transform: rotate3d(1, 1, 1, 360deg);
  }
}

點會出現在 planespoke 元素中以巢狀結構顯示,並使用轉換來縮放及轉譯點。這樣可以產生閃爍效果。

圓點會隨著球體和波浪旋轉。
.spoke-15 .dot,
.spoke-21 .dot {
  animation: pulsate 0.5s infinite 0.83333333s alternate both;
  background-color: #55ffee;
}

@-webkit-keyframes pulsate {
  0% {
    transform: rotateX(90deg) scale(0.3) translateZ(20px);
  }
  100% {
    transform: rotateX(90deg) scale(1) translateZ(0px);
  }
}

製作此動畫的工作,必須掌握正確的時間點,才能產生轉動和閃爍效果。動畫本身相當簡單,且採用的效能相當好的方法。

如果想查看動畫的成效,請開啟 Chrome 開發人員工具,並記錄執行期間的效能。初始載入後,動畫不會觸發版面配置或繪圖,且運作順暢。

結論

在這些範例中,您可以看看如何運用高效能方法為幾個屬性建立動畫,建立非常酷炫的動畫。如果預設採用動畫指南中所述的效能方法,您就能花時間建立所需效果,減少網頁載入速度變慢的問題。