高效能 CSS 動畫示例

本文將介紹 CodePen 上一些熱門動畫的製作方式。這些動畫都採用本節其他文章討論的高效能技術。

請參閱「為什麼有些動畫很慢?」一文,瞭解這些建議背後的理論,並參閱動畫指南,瞭解實用提示。

精靈載入動畫

在 CodePen 上查看精靈載入動畫

這個載入動畫完全使用 CSS 製作。圖片和所有動畫都是以 CSS 和 HTML 建立,不含圖片或 JavaScript。如要瞭解網頁的建立方式和成效,可以使用 Chrome 開發人員工具。

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

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

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

如要瞭解如何在不造成版面配置和繪製的情況下,實現這項動畫,請在 Chrome 開發人員工具中檢查任何移動元素。您可以使用「Animations Panel」找出各種動畫元素,點選任何元素都會在 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 開發人員工具中的「Performance」分頁,並錄製幾秒鐘的動畫。停止錄製,在瀑布圖中,您應該會看到沒有「Recalculate Style」項目。現在您知道這個動畫不會導致樣式重新計算,因此也不會觸發版面配置和繪製作業。

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

在 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: scale 和 opacity 加上動畫效果。

.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」面板。接著,您會看到所用動畫和動畫屬性的視覺化呈現。

選取 ::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);
  }
}

圓點位於 plane 和 spoke 元素內,並使用動畫,透過轉換來縮放及平移。這樣就能產生脈動效果。

圓點會隨著球體旋轉,並呈現脈動效果。
.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 開發人員工具,並在動畫執行時記錄效能。初始載入後,動畫不會觸發版面配置或繪製,且能順暢執行。

結論

從這些範例中,您可以瞭解如何使用高效能方法為幾個屬性建立動畫,進而建立一些非常酷炫的動畫。只要預設採用動畫指南所述的高效方法,您就能專心打造所需效果,不必擔心網頁速度變慢。