高效能 CSS 動畫示例

本文將說明如何建立 CodePen 上一些熱門動畫。這些動畫都使用本節其他文章中討論的高效能技術。

如要瞭解這些建議背後的理論,請參閱「為什麼部分動畫會變慢?」,如需實用提示,請參閱「動畫指南」。

精靈載入動畫

在 CodePen 上查看 Wizard 載入動畫

這個載入動畫完全是以 CSS 建構而成。 圖片和所有動畫都是以 CSS 和 HTML 建立,沒有圖片或 JavaScript。如要瞭解該廣告的建立方式和成效,可以使用 Chrome 開發人員工具。

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

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

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

如要瞭解如何達成這項動畫效果,且不會導致版面配置和繪製作業,請在 Chrome 開發人員工具中檢查任何移動的元素。您可以使用「動畫」面板找出各種動畫元素,點選任一元素即可在 DOM 中醒目顯示。

動畫面板,顯示動畫的各個部分。
在 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 上查看閃爍圓圈

這類動畫有時會用來吸引使用者注意網頁上的某個項目。 如要瞭解動畫,可以使用 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 開發人員工具中選取「動畫」面板。 接著,您會看到所用動畫的視覺化效果,以及動畫屬性。

選取 ::before 虛擬元素後,即可查看正在製作動畫的屬性。

白色圓圈本身是使用 ::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 Sphere

這項動畫看似非常複雜,但其實是使用先前範例中已見過的技術。複雜度來自於大量元素的動畫。

開啟 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 開發人員工具,並在動畫執行時記錄效能。 初始載入後,動畫不會觸發版面配置或繪製,而且會順暢執行。

結論

從這些範例中,您可以看到如何使用高效能方法為幾個屬性製作動畫,創造出非常酷炫的動畫。 預設使用動畫指南中說明的效能良好方法,您就能將時間花在建立所需效果上,不必擔心網頁速度變慢。