首頁 >web前端 >css教學 >使用Cupic-Bezier()高級CSS動畫

使用Cupic-Bezier()高級CSS動畫

Jennifer Aniston
Jennifer Aniston原創
2025-03-24 10:12:16670瀏覽

使用Cupic-Bezier()高級CSS動畫

在處理複雜的CSS動畫時,傾向於創建帶有許多聲明的擴展@KeyFrames。我想談論的一些技巧可能有助於使事情變得更容易,同時留在香草CSS中:

  1. 多個動畫
  2. 正時功能

第一個是更廣泛的使用和熟悉的,但第二個不太常見。可能有充分的理由 - 逗號的鏈接動畫比起我們可用的各種定時功能及其所做的工作要容易得多。有一個特別整潔的時序功能,可以使我們完全控制自定義的計時功能。那將是立方體bezier(),在這篇文章中,我將向您展示它的力量,以及如何使用它來創建精美的動畫而無需過多複雜。

讓我們從一個基本示例開始,顯示我們如何以有趣的方向移動球,例如無窮大(∞)形狀:

如您所見,沒有復雜的代碼 - 只有兩個關鍵幀和一個Cubbezier()函數。然而,我們得到的是一個相當複雜的最終無限形狀動畫。

酷,對吧?讓我們深入研究!

Cupic-Bezier()函數

讓我們從官方定義開始:

立方貝齊爾寬鬆函數是一種由四個實數定義的寬鬆函數,該函數分別指定了一個CubicBézier曲線的兩個控制點P1和P2,其端點P0和P3分別固定為(0,0)和(1,1,1)。 P1和P2的X坐標僅限於[0,1]的範圍。

上面的曲線定義了輸出(y軸)如何基於時間(x軸)的行為。每個軸的範圍為[0,1](或[0%100%])。如果我們有一個持續兩秒鐘(2s)的動畫,那麼:

 0(0%)= 0s 
1(100%)= 2s

如果我們想從5px到20px動畫,那麼:

 0(0%)= 5px 
1(100%)= 20px

X,時間始終僅限於[0 1];但是,輸出可以超越[0 1]。

我的目標是調整P1和P2,以創建以下曲線:

您可能會認為這是不可能實現的,因為如定義所述,P0和P3在(0,0)和(1,1)固定在(1,1)中,這意味著它們不能在同一軸上。的確如此,我們將使用一些數學技巧來“近似”它們。

拋物線曲線

讓我們從以下定義開始:Cubic-Bezier(0,1.5,1,1.5)。這給了我們以下曲線:

我們的目標是移動(1,1),並以(0,1)的形式搬遷,這在技術上是不可能的。因此,我們將嘗試偽造它。

我們先前說過,我們的範圍是[0 1](或[0%100%]),因此讓我們想像一下,當0%非常接近100%時。例如,如果我們希望將20px(0%)至20.1px(100%)的頂部動畫起來,那麼我們可以說初始狀態和最終狀態都是相等的。

嗯,但是我們的元素根本不會移動,對嗎?

好吧,它會移動一點,因為y值超過20.1px(100%)。但這還不足以給我們帶來明顯的運動:

讓我們更新曲線,然後使用Cupic-Bezier(0,4,1,4)。注意我們的曲線比以前高:

但是,即使最高值越過3(或300%),但仍然沒有運動。讓我們嘗試立方體bezier(0,20,1,20):

是的!它開始移動一點。您是否每次提高價值時都注意到曲線的演變?當我們放大以查看完整曲線時,這使我們的觀點(1,1)更接近(0,1),這是訣竅。

通過使用Cutic-Bezier(0,V,1,V),其中V具有很大的值,並且初始狀態和最終狀態都非常近(或幾乎相等),我們可以模擬拋物線曲線。

一個例子值得一千個字:

我將“魔術”立方呈現功能應用於頂部動畫,以及在左側應用的線性動畫。這為我們提供了想要的曲線。

挖掘數學

對於那些以數學意識的人來說,我們可以進一步打破這一解釋。可以使用以下公式來定義立方體bezier:

 p =(1 -t)³p03(1 -t)²TP13(1 -t)t第一p2t³p3

每個點的定義如下:p0 =(0,0),p1 =(0,v),p2 =(1,v)和p3 =(1,1)。

這為我們提供了X和Y坐標的兩個功能:

  • x(t)= 3(1 -t)t²T³=3t² -2t³
  • y(t)= 3(1 -t)²TV3(1 -t)t²vt³=t³ -3vt²3vt

V是我們的最大價值,T在[0 1]範圍內。如果我們考慮上一個示例,y(t)將為我們提供頂部的價值,而x(t)是時間進度。點(x(t),y(t))然後將定義我們的曲線。

讓我們找到y(t)的最大值。為此,我們需要找到將為我們提供y'(t)= 0的t值(當導數等於0時):

 y'(t)=3T² -6VT 3V

y'(t)= 0是二次方程。我將跳過無聊的部分,並為您提供結果,即t = v -sqrt(v² -v)。

當V為較大的值時,t將等於0.5。因此,y(0.5)= max和x(0.5)等於0.5。這意味著我們在動畫中的中途達到最大值,這符合我們想要的拋物線曲線。

另外,y(0.5)將為我們提供(1 6V)/8,這將使我們能夠基於V。我們始終使用V的最大值,因此我們可以簡化為6V/8 = 0.75V。

我們在上一個示例中使用了v = 500,因此那裡的最大值將達到375(或37500%),我們得到以下內容:

  • 初始狀態(0):頂部:200px
  • 最終狀態(1):頂部:199.5px

在0到1之間的差異為-0.5px。讓我們稱其為增量。對於375(或37500%),我們的方程為375*-0.5px = -187.5px。我們的動畫元素達到頂部:12.5px(200px -187.5px),並為我們提供以下動畫:

頂部:200px(時間為0%)→頂部:12.5px(時間為50%)→頂部:199.5px(在100%的時間為100%) 

或者,以另一種方式表示:

頂部:200px(0%)→頂部:12.5px(50%)→頂部:200px(100%)

讓我們做相反的邏輯。我們應該使用什麼值來使元素達到頂部:0px?動畫將為200px→0px→199.5px,因此我們需要-200px才能達到0px。我們的增量始終等於-0.5px。最大值將等於200/0.5 = 400,因此0.75V = 400,表示V = 533.33。

我們的元素正在觸及頂部!

這是一個總結我們剛剛完成的數學的數字:

正弦曲線

我們將使用幾乎完全相同的技巧來創建正弦曲線,但具有不同的公式。這次,我們將使用立方體bezier(0.5,V,0.5,-v)

像以前一樣,讓我們​​看看曲線在增加價值時會如何發展:

我認為您現在可能已經明白了。使用v的大價值使我們接近正弦曲線。

這是另一個具有連續動畫的動畫 - 真正的正弦動畫!

數學

讓我們來數學吧!與以前相同的公式填充,我們將獲得以下功能:

  • x(t)= 3/2(1 -t)²T3/2(1 -t)t²T³=(3/2)t - (3/2)t²T³
  • y(t)= 3(1 -t)²TV -3(1 -t)t²vt³=(6v 1)t³ -9vt²3vt

這次我們需要找到y(t)的最小值和最大值。 y'(t)= 0將為我們提供兩個解決方案。解決此問題之後:

 y'(t)= 3(6v 1)t² -18vt 3v = 0

…我們得到:

  • t'=(3v sqrt(3v² -v))/(6v 1)
  • t''=(3v -sqrt(3v² -v))/(6v 1)

對於V的很大價值,我們具有t'= 0.211和t“ = 0.789。這意味著y(0.211)= max and y(0.789)= min。這也意味著x(0.211)= 0.26和x(0.789)= 0.74。

Y(0.211)等於0.289V和Y(0.789)至-0.289V。考慮到V非常大,我們得到了一些舍入的價值。

我們的正弦曲線還應在一半時間(或x(t)= 0.5)的x軸(或y(t)= 0)穿越x軸(或y(t)= 0)。為了證明這一點,我們使用y(t)的第二個衍生物 - 應等於0-因此,y''(t)= 0。

 y''(t)= 6(6v 1)t -18v = 0

解決方案為3V/(6V 1),對於大V值,解決方案為0.5。這給我們y(0.5)= 0和x(0.5)= 0.5,這證實了我們的曲線交叉(0.5,0)點。

現在,讓我們考慮上一個示例,然後嘗試找到V的值,該值使我們回到頂部:0%。我們有:

  • 初始狀態(0):頂部:50%
  • 最終狀態(1):頂部:49.9%
  • 增量:-0.1%

我們需要-50%才能達到頂部:0%,因此0.289V*-0.1%= -50%,這使我們v = 1730.10。

如您所見,我們的元素正在觸摸頂部並在底部消失,因為我們有以下動畫:

頂部:50%→頂部:0%→頂部:50%→頂部:100%→頂部:50%→等等...

總結計算的數字:

以及一個一起說明所有曲線的示例:

是的,您會看到四個曲線!如果仔細觀察,您會注意到我使用的是兩個不同的動畫,一個將達到49.9%(增量為-0.01%),另一個將達到50.1%(增量為0.01%)。通過更改增量的符號,我們控製曲線的方向。我們還可以控制立方bezier的其他參數(不是應保持大價值的V),以從相同的曲線中創建更多變化。

在下面,一個互動演示:

回到我們的例子

讓我們回到我們最初以無限符號形狀移動的球的最初示例。我只是將兩個正弦動畫結合起來,使其起作用。

如果我們將以前所做的工作與多個動畫的概念結合在一起,我們就會獲得驚人的結果。這再次是最初的示例,這次是交互式演示。改變價值並看到魔術:

讓我們走得更遠,在混合物中加入一點CSS Houdini。多虧了@property,我們可以為複雜的轉換聲明動畫(但目前CSS Houdini僅限於Chrome和Edge支持)。

您可以用什麼樣的圖紙?這是我能夠製作的一些:

這是一個動畫:

還有一個沒有CSS Houdini的版本:

從這些示例中可以看出一些事情:

  • 每個密鑰幀僅使用一個包含增量的聲明來定義。
  • 元素和動畫的位置是獨立的。我們可以輕鬆地將元素放置在任何地方,而無需調整動畫。
  • 我們沒有進行計算。沒有大量的角度或像素值。我們只需要在密鑰幀中一個很小的值,並且在Cux-Bezier()函數中需要一個大價值。
  • 整個動畫只能通過調整持續時間值來控制。

那過渡呢?

同一技術也可以與CSS過渡屬性一起使用,因為它在定時功能時遵循相同的邏輯。這很棒,因為在創建一些複雜的懸停效果時,我們能夠避免使用密鑰幀。

這是我沒有密鑰幀的方法:

馬里奧(Mario)借助拋物線曲線了。我們根本不需要鑰匙幀就可以在懸停的搖動動畫上創建動畫。正弦曲線完全有能力完成所有工作。

這是Mario的另一個版本,這次是使用CSS Houdini。而且,是的,由於拋物線曲線,他仍在跳躍:

為了良好的衡量,這裡是沒有密鑰幀的更精美的懸停效果(同樣,僅鍍鉻和邊緣):

就是這樣!

現在,您有了一些魔術立方體()曲線曲線以及它們背後的數學。當然,好處是這樣的自定義定時功能使我們可以在沒有我們通常可以遇到的複雜關鍵框架的情況下進行精美的動畫。

我知道並非每個人都有數學意識,沒關係。有一些可以提供幫助的工具,例如Matthew Lein的Ceaser,它使您可以將曲線點拖動以獲取所需的東西。而且,如果您還沒有書籤,Cupic-bezier.com是另一個。如果您想在CSS世界之外與Cupic-Bezier一起玩,我建議您在這裡看到一些數學公式。

無論您如何獲得立方bezier()值,希望現在您對它們的力量以及它們如何幫助在此過程中製作更好的代碼。

以上是使用Cupic-Bezier()高級CSS動畫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:第8章:CSS下一篇:第8章:CSS