CSS動畫中的貝塞爾

發表於2015-11-21

介紹篇:

貝塞爾曲線,法國數學家Pierre Bézier製造。

一種繪製曲線的方法,配有詳細的計算公式,按照這樣的公式繪製出來的曲線是為貝塞爾曲線。

其在計算機圖形中的應用相當廣泛,幾乎有曲線的地方,就少不了它的身影,如在Photoshop,Flash,CorelDRAW中的使用。

常見貝塞爾曲線示例圖:

一階貝塞爾曲線(線段)

bezier-01

二階貝塞爾曲線(拋物線)

bezier-02

三階貝塞爾曲線

bezier-03

其在CSS動畫中的使用,簡單的說,就是在動畫的運動過程中,控制速率的變化。

bezier-04

進階篇:

CSS動畫中使用的是三階曲線,如下圖所示,三階曲線共有P0,P1,P2,P3四個節點,其中P0是起點、P3是終點,P1和P2是控制點。同時CSS中使用的曲線,有些特殊,它固定了起點P0(0,0)和終點P3(1,1),僅有控制點可以移動。移動控制點可以改變曲線的曲率(彎曲的程度),通過曲率的變化反映出速率的變化,應用於動畫之中。

bezier-01

之後我們來看下曲率對應速率變化的規律。X軸和Y軸,我們理解為時間軸和距離變化軸,那麼單位時間內,距離變化的多少,反應出來的就是速度的快慢。

下圖中,X軸的切分是均等的,同時虛線矩形內,x1對應的y1、x2對應的y2,也是相等的,那麼認為起點到終點是勻速變化的。

bezier-02

下圖中,X軸的切分是均等的,同時虛線矩形內,x1對應的y1 大於 x2對應的y2,那麼認為起點到終點的運動過程中,速度是先快後慢的。

bezier-03

這兩種曲線反應到具體的動畫之中的效果如下。

bezier-04

CSS動畫中,使用貝塞爾曲線作為值的屬性有兩個,transition-timing-function,animation-timing-function,格式為cubic-bezier(P1x,P1y,P2x,P2y),實際應用中的程式碼例項 transition: all 3.0s cubic-bezier(0.75, 0.25, 0.25, 0.75)。

可能你大多看到的是,ease,linear,ease-in-out 這樣的屬性值,其實它們也是貝塞爾曲線值,只不過是官方預定義的,以簡化明瞭的名稱,替代了複雜的數值書寫方式。

以下是一些預定義名稱對應的曲線值:

ease: cubic-bezier(0.25, 0.1, 0.25, 1.0)
linear: cubic-bezier(0.0, 0.0, 1.0, 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)

深入篇:

1)邊界和峰值

前面提到過,CSS中的曲線是固定了起點P0(0,0)和終點P3(1,1)的,那麼可直觀的認為 X 和 Y 的取值範圍是0 – 1。但實際使用中,僅 Y 的取值是允許超出範圍的。

如果 X 的取值超出範圍,瀏覽器會認為屬性值非法,而無法正常執行動畫。如果 Y 取值超出範圍,因為 Y 表示的是距離,所以表示出來就是運動距離超出邊界或者運動距離反向變小,然後再繼續運動到終點,想象出來了嗎,是的,這是回彈效果。

峰值表示速度達到最大或最小,很短暫的停留後,再降速或加速到達終點。因為僅有兩個控制點,所以會有一個或者兩個峰值,表示有一個或者兩個速度轉折到過程。可以利用峰值,更好的實現動畫來表現自己要傳達的引導意識。

bezier-06

2)視差

鑑於更好的理解,上文都是以運動距離屬性,來形象的表達動畫。貝塞爾曲線表示的是速率,那麼基本上可以連續變化的屬性,都可以應用,而不僅僅是距離,比如顏色,透明度,尺寸,縮放,翻轉等等。如果再加上不同的動畫延遲時間,不同的動畫運動持續時間,就會產生酷炫的視差效果。

3)案例

刀子磨好了,可以上手試試咯,先看下最終效果吧

bezier-07

仔細看幾遍就會發現,其實五個點的動畫是一樣的,僅僅是作用了不同的延遲時間,就產生了很高大上的視覺效果。那我們現在拆分出單個點的動畫,再來觀察,看下圖:

bezier-08

可以觀察到以下幾個細節:

1. 圓點起初是不可見的,動畫的最後是漸隱的,可以用opacity實現。

2. 圓點的運動軌跡是圓周運動,可以用rotate實現。

3. 在速度上,可以分為幾個階段,先由快到慢,然後勻速,然後慢到快再到慢,然後勻速,最後再由快到慢。

OK,可以下手寫程式碼了,我們依照速度的變化規律,把整個動畫劃分為多個階段,為每個階段寫上當前的終點樣式,包括旋轉角度、透明度值。現在動畫已經可以執行了,只是不夠酷,因為CSS中貝塞爾曲線的預設值,即是 linear: cubic-bezier(0.0, 0.0, 1.0, 1.0),[勻速],所以動畫的每個階段都是勻速變化的。

bezier-09

現在我們為每個階段加上,已經調出的貝塞爾曲線取值,再看下效果,是不是和最終效果一樣了。

bezier-07

最終程式碼如下,大家可以藉助文章最後給出的工具,自己多多試試,然後在程式碼裡改成自己的貝塞爾曲線,看看效果吧。

備註:以下是兩個可以即時除錯曲線的頁面應用

http://cubic-bezier.com/
http://www.css3beziercurve.net/

相關文章