了解 CSS 動畫和過渡的緩動函數

已發表: 2022-03-10
快速總結↬緩動函數可以通過影響動畫的速率或速度來改變動畫的外觀和感覺。 作為人類,我們習慣於自然的非線性運動。 在動畫中使用這些自定義緩動功能可以改善用戶印象和更愉快的用戶體驗。 在本文中,我們將深入探討緩動函數,看看我們如何使用它們來創建那些自然而令人驚嘆的動畫。

你有沒有註意到一個製作精良的專業項目的動畫看起來是多麼流暢和令人愉快? 我想起了 In Pieces 網站,其中動畫不僅用於裝飾,而且還以一種有影響力的方式傳達有關瀕危物種的信息。 不僅動畫設計和風格優美,而且流暢和諧。 正是這種流動與設計和演示相結合,使動畫看起來令人驚嘆和自然。 這就是緩動函數的威力,也稱為計時函數。

在 CSS 中編寫過渡和動畫屬性時,我們通常會使用預定義的緩動函數,比如ease-out因為它很簡單,看起來還不錯,並且在大多數情況下都能很好地工作。 但是,如果頁面上有十幾個或更多元素的動畫具有相同的持續時間和緩動函數值,可能會使 UI 有點乏味和單調。 人類對自然運動的反應更好,因此使動畫和過渡更加多樣化和自然將帶來更好的用戶體驗。

如果我們回到 In Pieces 示例並檢查樣式表,我們會注意到各種自定義cubic-bezier函數與預定義的linear ease-in計時函數結合使用,以實現漂亮的動畫流程。 如果只使用預定義的緩動函數而不是自定義緩動函數,動畫看起來不會那麼好。 以下視頻展示了 In Pieces 網站,其中所有緩動功能都設置為ease-out 。 儘管動畫沒有任何問題,但請注意它們並不像原始動畫那樣令人驚嘆或令人興奮。

在本文中,我們將深入探討 CSS 緩動函數、緩動函數的類型以及如何使用三次貝塞爾曲線創建自定義緩動函數。

跳躍後更多! 繼續往下看↓

引擎蓋下

為了更好地理解緩動函數,我們需要退後一步,看看 CSS 中的動畫基礎知識。

動畫由關鍵幀定義,這些關鍵幀決定元素的外觀和在特定點的位置。 CSS 過渡使用兩個關鍵幀(開始值和結束值),而 CSS 動畫允許使用@keyframes規則進行更精確的控制。

從左到右從 0px(0% 動畫輸出)移動到 500px(100% 動畫輸出)的框的動畫輸出(關鍵幀)示例
從左到右從 0px(0% 動畫輸出)移動到 500px(100% 動畫輸出)的框的動畫輸出(關鍵幀)示例。 (大預覽)

動畫持續時間決定了動畫從第一個關鍵幀到最後一個關鍵幀的時間量。 下圖顯示了動畫關鍵幀和持續時間之間的聯繫。

一個盒子的動畫輸出示例,它從 0px(0% 動畫輸出)移動到 500px(100% 動畫輸出),持續時間為 1000 毫秒。兩點由直線連接。
一個盒子的動畫輸出示例,它從 0px(0% 動畫輸出)移動到 500px(100% 動畫輸出),持續時間為 1000 毫秒。 兩點由直線連接。 (大預覽)

動畫可以通過多種方式在兩個關鍵幀之間進行。 例如,動畫可以有一個恆定的速度,或者它可以在開始時快速移動並在接近結束時減速,或者在開始時緩慢移動然後加速直到到達終點,等等。這個速率或速度定義為緩動功能(計時功能) 。 如果我們看一下上圖,緩動函數由連接兩點的線的形狀表示。 我們在前面的例子中使用了線性函數(直線),但我們也可以使用曲線來連接關鍵幀。

從 0px(第一個關鍵幀)移動到 500px(最後一個關鍵幀)且持續時間為 1000 毫秒的框的動畫輸出示例。動畫將在起始關鍵幀處加速並在最後一個關鍵幀附近減速。
從 0px(第一個關鍵幀)移動到 500px(最後一個關鍵幀)且持續時間為 1000 毫秒的框的動畫輸出示例。 動畫將在起始關鍵幀處加速並在最後一個關鍵幀附近減速。 (大預覽)

如您所見,動畫緩動函數有很多可能的選項和變體,接下來我們將看看它們。

緩動函數的類型

在 CSS 中可以使用三種主要類型的緩動函數:

  • 線性函數( linear ),
  • 三次貝塞爾函數(包括ease , ease-in , ease-outease-in-out ),
  • 樓梯功能( steps )。

線性函數

我們已經在前面的一個示例中介紹了線性函數,所以讓我們快速回顧一下。 使用線性定時功能,動畫以恆定速度通過關鍵幀。 您可能已經知道,線性定時功能可以通過使用linear關鍵字在 CSS 中輕鬆設置。

一個盒子的動畫輸出示例,它從 0px(0% 動畫輸出)移動到 500px(100% 動畫輸出),持續時間為 1000 毫秒。
一個盒子的動畫輸出示例,它從 0px(0% 動畫輸出)移動到 500px(100% 動畫輸出),持續時間為 1000 毫秒。 (大預覽)
從 0px(第一個關鍵幀)移動到 200px(第二個關鍵幀)然後到 500px(最終關鍵幀)的框的動畫輸出示例,持續時間為 1000 毫秒。
從 0px(第一個關鍵幀)移動到 200px(第二個關鍵幀)然後到 500px(最終關鍵幀)的框的動畫輸出示例,持續時間為 1000 毫秒。 (大預覽)

請參閱 Adrian Bece 的鋼筆 [動畫 - 線性](https://codepen.io/smashingmag/pen/Bapbgxg)。

請參閱 Adrian Bece 的鋼筆動畫 - 線性。

三次貝塞爾函數

雖然線性計時函數有其用例,但如果使用不當或過於頻繁,它們會使動畫看起來平淡無奇和不自然。 正如我們從 In Pieces 示例中看到的那樣,用戶對自然運動的反應更好,即可以加速和減速的非線性計時函數。

貝塞爾曲線常用於矢量圖形、動畫和機器人技術,以輕鬆創建平滑曲線和軌跡。 在 CSS 中,我們使用由四個點定義的貝塞爾曲線,稱為三次貝塞爾曲線。

常用的預定義緩動函數如easeease-inease-outease-in-out屬於 Cubic Bezier 函數。 它們可以用作設置非線性緩動函數的快速方法。 甚至可以使用cubic-bezier函數定義線性函數。

緩動功能cubic-bezier啟動速度中速結束速度
linear cubic-bezier(0.0, 0.0, 1.0, 1.0) 持續的持續的持續的
ease cubic-bezier(0.25, 0.1, 0.25, 1.0) 快速加速快速加速慢加速
ease-in cubic-bezier(0.42, 0, 1.0, 1.0) 慢加速快速加速全速
ease-out cubic-bezier(0, 0, 0.58, 1.0) 全速慢加速慢加速
ease-in-out cubic-bezier(0.42, 0, 0.58, 1.0) 慢加速全速快速加速

儘管預定義的值在許多情況下都可以很好地工作,但知道如何創建自定義三次 Bezier 函數可以讓您更好地控制動畫的外觀和感覺,從而使動畫看起來更加令人印象深刻和有影響力。

在以下示例中,我編輯了 In Pieces 示例的動畫以使用具有不同值的不同 Cubic Bezier 函數。 您可以使用此緩動功能看到動畫的外觀和感覺有多麼不同。

 cubic-bezier(0, 1.2, 1, 0.2)

讓我們看一下在 CSS 中用於定義 Cubic Bezier 曲線的cubic-bezier函數。 三次貝塞爾函數由四個點(x 和 y 坐標對)定義,但我們在cubic-bezier貝塞爾函數中只定義了 2 個點。 這是為什麼?

CSS 動畫的三次貝塞爾曲線示例。
CSS 動畫的三次貝塞爾曲線示例。 (圖片來源:MDN Web docs)(大預覽)

這是因為第一個點(P0)和最後一個點(P3)固定在曲線的開始(初始動畫狀態)和結束(最終動畫狀態),因為動畫需要在指定的關鍵幀和指定的範圍內結束期間。 使用剩下的兩個點(P1 和 P2),我們可以微調函數的曲線和緩動,從而獲得非線性動畫速度。

 cubic-bezier(x1, y1, x2, y2)

X 坐標( x1x2 )表示時間比例,並且限制在 0 和 1 之間的值(動畫不能比指定的更早或持續時間更長),而 Y 坐標( y1y2 )表示動畫輸出及其值,它們是通常設置在 0 和 1 之間,但不限於該範圍。 我們可以使用 0 和 1 範圍之外的y1y2值來創建彈跳效果。

具有彈跳效果的動畫
(大預覽)

如果動畫由幾個關鍵幀組成,在 CSS @keyframes屬性中定義,緩動函數將應用於兩點之間的每條曲線。 如果我們將ease-out功能應用於具有 3 個關鍵幀的動畫,動畫將在第一個關鍵幀開始處加速,並在第二個關鍵幀附近減速,並且下一對關鍵幀(第二個關鍵幀和最後一個關鍵幀)。

請參閱 Adrian Bece 的 Pen [Cubic-bezier functions 2 keyframes](https://codepen.io/smashingmag/pen/zYNbVME)。

請參閱 Adrian Bece 的 Pen Cubic-bezier functions 2 keyframes。

注意緩動函數是如何在每個關鍵幀對之間重複的——第一個和第二個關鍵幀(第一對),第二個關鍵幀和最後一個關鍵幀(第二對)。 前面和下面的示例的動畫持續時間相同。

請參閱 Adrian Bece 的 Pen [Cubic Bezier functions 3 keyframes](https://codepen.io/smashingmag/pen/KKaEjbM)。

請參閱 Adrian Bece 的 Pen Cubic Bezier 函數 3 個關鍵幀。

創建這些函數可能是一項複雜的任務,因此您可能不會通過猜測cubic-bezier參數來調整坐標。 您必須使用一種工具來幫助您確定這些神奇的數字,以便創建一個完全適合您的動畫的計時功能。 幸運的是,有許多瀏覽器和在線工具可以幫助我們。 我們將在本文的以下部分之一中討論它們。

樓梯功能

樓梯函數使動畫能夠以非連續方式在特定數量的幀之間跳轉。 你可以把它想像成一個“滴答”的動畫。

例如,如果我們看一下前面的一個例子,其中一個盒子從 0px 移動到 500px,並且我們將動畫限制為 5 步,動畫將在以下 5 個關鍵幀之間跳轉——0px、100px、200px、300px 和 400px職位。

我們可以通過 CSS 中的steps功能輕鬆實現這一點。

 steps(number_of_frames)
 steps(5)

此函數有一個附加選項,用於控制包含哪些關鍵幀。 正如你從前面的例子中看到的,一個盒子從 0px 移動到 500px 5 步的動畫將在 400px 的位置結束。 如果我們希望動畫從 100px 開始並在 500px 位置結束,我們可以使用jump term選項作為第二個參數。 跳轉項影響如何從動畫時間軸中選擇關鍵幀。

 steps(number_of_frames, jump_term)
 steps(5, jump-start)

在 CSS steps函數中可以使用以下跳轉項選項:

  • jump-start
    動畫從起點直接跳轉,起點不可見 t。 在我們的示例中,關鍵幀將是 100px、200px、300px、400px、500px。
  • jump-end
    最後一次跳轉發生在動畫結束且不可見時。 在我們的示例中,關鍵幀將是 0px、100px、200px、300px、400px。
  • jump-both
    第一次和最後一次跳躍都將分別在動畫開始和結束時發生,因此它們不可見。 所有 5 次跳躍都將發生在凝視點和結束點之間。 在我們的示例中,這些關鍵幀將是 80px、165px、250px、335px、420px。
  • jump-none
    第一次和最後一次跳躍都是可見的。 在我們的示例中,這些關鍵幀將是 0px、125px、250px、375px、500px。
持續時間為 1000 毫秒的步驟 (5) 動畫的時間軸
step(5) 動畫的時間軸,持續時間為 1000 毫秒。 (大預覽)

以下示例展示了各種跳轉項如何影響動畫行為。 不同的跳躍項應用於具有相同持續時間的 5 步動畫。

請參閱 Adrian Bece 的 Pen [Step function](https://codepen.io/smashingmag/pen/ZELPdPK)。

請參閱 Adrian Bece 的 Pen Step 功能。

調試動畫和有用的工具

正如我們從 Cubic Bezier 示例中看到的那樣,我們需要某種工具來幫助我們微調 Cubic Bezier 曲線參數,以便我們可以實現我們想要的動畫的外觀和感覺。

在本節中,我們將了解應該幫助我們做到這一點的瀏覽器工具、網站和 CSS 樣式。

瀏覽器工具

瀏覽器開發者工具提供了開箱即用的有用的緩動函數編輯特性。 請注意,只有三次 Bezier 函數可用於編輯。 這些工具提供了快速簡單的動畫預覽,以便開發人員能夠獲得即時反饋並微調緩動功能。

鉻,Safari,火狐。
鉻,Safari,火狐。 (大預覽)

Chrome、Safari 和 Firefox 還在開發者工具中提供了一個專門的動畫選項卡,提供更詳細的概述,包括動畫屬性、持續時間、時間線、關鍵幀、延遲等。

鉻,Safari,火狐。
鉻,Safari,火狐。 (大預覽)

有用的工具和網站

有大量有用的在線資源和緩動預設可以為緩動功能提供更多種類。

更受歡迎的在線資源包括 Andrey Sitnik 和 Ivan Solovev 的 Easing Functions Cheat Sheet 以及 Matthew Lein 的 CSS Easing Animation Tool。 這些工具提供了廣泛的預設,您可以將其用作緩動功能的基礎,然後微調曲線以適合您的動畫時間線。

Easing Functions Cheat Sheet 包含 30 個有用的 Cubic Bezier 函數預設
Easing Functions Cheat Sheet 包含 30 個有用的功能預設。 (大預覽)

動畫和可訪問性

通常在使用緩動函數和動畫時,解決可訪問性要求很重要。 有些人喜歡以減少動作瀏覽網頁,所以我們應該提供適當的後備。 這可以通過廣泛支持的偏好減少運動媒體查詢輕鬆完成。 此媒體查詢允許我們刪除動畫或根據用戶偏好分配不同的動畫。

 .animated-element { animation: /* Regular animation */; } @media (prefers-reduced-motion) { .animated-element { /* Accessible animation with reduced motion */ } }

我修改了 Alvaro Montoro 的模擬時鐘示例,為設置了prefers-reduced-motion標誌的用戶提供了替代動畫。

請參閱 Adrian Bece 的 Pen [CSS 模擬時鐘,更喜歡減少運動](https://codepen.io/smashingmag/pen/QWdoXPN)。

請參閱 Adrian Bece 的 Pen CSS Analog Clock,它更喜歡減少運動。

在默認動畫中,時鐘的秒針不斷移動,這可能會給某些用戶帶來困難。 通過將動畫計時功能更改為steps ,我們可以輕鬆地使動畫更易於訪問。 在以下示例中,設置了prefers-reduced-motion標誌的用戶將顯示一個動畫,其中秒臂每五秒滴答一次。

 @media (prefers-reduced-motion) { .arm.second { animation-timing-function: steps(12); } }

結論

緩動函數或計時函數通過影響動畫速率(速度)來改變動畫的外觀和感覺。 緩動功能使我們能夠創建類似於自然運動的動畫,從而改進、更令人愉悅的用戶體驗並給用戶留下更好的印象。 我們已經了解瞭如何使用linearease-outease動等預定義值來快速添加計時函數,以及如何使用cubic-bezier函數創建自定義緩動函數以獲得更令人印象深刻和有影響力的動畫。 我們還介紹了可用於創建“滴答”動畫但很少使用的樓梯函數。 在創建動畫時,重要的是要牢記可訪問性,並為設置了prefers-reduced-motion標誌的用戶提供一種替代的、較少分散注意力的動畫和較少的運動。

有大量的瀏覽器和在線工具可以簡化和簡化創建自定義緩動函數,因此創建具有漂亮流程的動畫比以往任何時候都容易。 如果您還沒有這樣做,我建議您嘗試各種緩動函數並創建自己的緩動函數庫。

參考

  • <easing-function> , MDN 網絡文檔
  • “使用動畫”,MDN 網絡文檔
  • “Safari 13.1 中的 Web 動畫”,Antoine Quint,WebKit
  • “Easing 的基礎”,Paul Lewis,Web Fundamentals,Google 開發者
  • “檢查動畫”,Kayce Basques,Chrome DevTools,Chrome 開發人員