如何理解並應用貝塞爾曲線

貝塞爾曲線又叫貝茲曲線,在大學高數中一度讓我很是頭疼。前陣子練手寫動畫的時候,發現貝塞爾曲線能夠應用於軌跡的繪製以及定義動畫曲線。css

本文就來探究一下,貝塞爾曲線究竟是個什麼樣的存在。html

貝塞爾曲線原理

貝塞爾曲線由n個點來決定,其曲線軌跡能夠由一個公式來得出:前端

貝塞爾公式

其中n就表明了貝塞爾曲線是幾階曲線,該公式描述了曲線運動的路徑。git

如下咱們來討論一下,貝塞爾公式如何推導。github

一階貝塞爾曲線

一階

設定圖中運動的點爲Pt,t爲運動時間,t∈(0,1),可得以下公式canvas

公式1

二階貝塞爾曲線

二階

二階座標

在二階貝塞爾曲線中,已知三點恆定(P0,P1,P2),設定在P0P1中的點爲Pa,在P1P2中的點爲Pb,Pt在PaPb上的點,這三點都在相同時間t內作勻速運動。api

由公式(1)可知bash

公式2

將公式(2)(3)代入公式(4)中,可得函數

公式3

三階貝塞爾曲線

三階

三階座標

同理,根據以上的推導過程可得工具

公式4

由此能夠推導

公式5

n階貝塞爾曲線

四階

五階

放上一個網址,隨意感覺一下貝塞爾曲線的繪製過程:

曲線繪製

實際應用

貝塞爾曲線在前端中主要有兩方面的應用,一方面能夠做爲動畫曲線應用於CSS3動畫中;另外一方面能夠經過canvas來繪製曲線達到須要的效果。

CSS3中貝塞爾曲線的應用

在CSS3中,有兩屬性常常被用到:transition-timing-functionanimation-timing-function,這兩個分別表明了過渡的速度和動畫的速度。CSS3爲咱們提供了一個新的工具——cubic-bezier(x1,y1,x2,y2)。這個工具可以生成一個速度曲線,使咱們的元素按照該曲線來調節速度。

在上面的推導中,咱們知道在貝塞爾公式中,有兩個點的位置恆定——P0和P1,cubic-bezier中定義了兩個控制點的位置,因此該曲線爲三階貝塞爾曲線。

有個網站能夠方便咱們快速創建一個貝塞爾曲線:cubic-bezier

貝塞爾曲線與動畫曲線的關聯

先來一波動圖簡單粗暴的感覺一下: 例一:

1

例二:

2

例三:

3

左邊的是貝塞爾曲線,橫軸表明了事件,豎軸表明了進度,沒法直觀得感覺出速度的變化。

右邊的曲線是控制面板中的動畫曲線,橫軸是時間,豎軸是速度,能夠方面地看出速度的變化。

上述例子中,之前進反向爲速度正方向,後退方向爲速度反方向。

如何得知速度的變化

推導

例一中,貝塞爾曲線爲一條直線,當時間均勻變化時,進度也在均勻變大,由此可知速度恆定不變,時間和進度之間的關係能夠用一個線性方程來表示:

y=ax+b (a=1,b=0)
複製代碼

其中x爲時間,y爲進度,a即爲速度。

推導案例一

從上面結論中啓發,去觀察其餘貝塞爾曲線,

方程一

圖中是一段變化的曲線,咱們取其中一小段,將其看做穩定不變的一段直線,經過下面的線性方程來表示,並經過紅線標註在圖中:

y=ax+b
複製代碼

根據初中數學的內容,咱們知道,當a>1時,與x軸的夾角∈(45°,90°);當a∈(0,1)時,與x軸的夾角在(0,45°)之間。相同的時間內,與x軸的夾角越大,a越大,速度越快。

觀察上圖的夾角變化趨勢,夾角逐漸變小趨向於0,然後逐漸變大,趨向於90°,對應速度應是速度逐漸變慢趨向於0,以後逐漸變快。

放上動畫曲線以及動圖來驗證一下咱們的推測:

方程一(1)

5

推導案例二

下圖中的曲線部分在第四象限,部分在第一象限,這時對應的動畫曲線該如何推導呢。

一樣將該曲線視爲由n段平滑的直線構成,由線性方程來表示直線的趨勢,可知速度a方向一開始爲負,以後慢慢向正方靠近,a的速率也在由大變小,當爲0時,再向正方慢慢變大。即該曲線表示元素一開始在朝反方向減速運動,當速度爲0後,向正方向做加速運動。

方程三

經過動畫曲線及動圖來驗證上述推導:

方程三(1)

6

驗證

用兩個曲線來驗證一下上面的結論:

曲線一:

方程二

方程二(1)

3

曲線二:

方程四

方程四(1)

7

從結果能夠判斷,用上述推導方法能夠正確得出貝塞爾曲線與動畫曲線之間的關係。

動畫曲線的應用

瞭解瞭如何用貝塞爾曲線來指定動畫曲線後,不少動畫涉及到速度方面的效果就能夠實現了,例如小車加速剎車,彈簧動畫等速度軌跡均可以根據本身的須要來進行定製。

放上一個緩動函數速查網址,可讓本身的動效更加真實:緩動函數

放一個小例子:

動畫案例

該動畫模擬了小球落下回彈的過程

代碼以下:

<div class="ground">
      <div class="ball" id="ball"></div>
    </div>
複製代碼
.ball {
        width: 30px;
        height: 30px;
        background: #000000;
        border-radius: 50%;
        position: absolute;
        top: 0;
        left: 50%;
        animation: move 4s cubic-bezier(0.36, 1.7, 0.26, 0.61) 1s infinite;
      }

      @keyframes move {
        0% {
          top: 0;
        }
        100% {
          top: 90%;
        }
      }
複製代碼

這類動畫能夠參考網上大大們的案例:

貝塞爾曲線與CSS3動畫、SVG和canvas的應用

理解與運用貝塞爾曲線

利用canvas繪製貝塞爾曲線

canvas中提供了api能夠快速繪製一條貝塞爾曲線,來達到須要的效果:

二階貝塞爾曲線

quadraticCurveTo(x1,y1,x2,y2)

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.quadraticCurveTo(40,200,200,20);
ctx.stroke();
複製代碼

canvas-2階

其中moveTo定義了起始點,quadraticCurveTo(x1,y1,x2,y2)中的(x1,y1)爲控制點,(x2,y2)爲終點

三階貝塞爾曲線

bezierCurveTo(x1,y1,x2,y2,x3,y3)

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.bezierCurveTo(40,100,200,150,200,20);
ctx.stroke();
複製代碼

canvas-3階

其中moveTo定義了起始點,bezierCurveTo(x1,y1,x2,y2)中的(x1,y1),(x2,y2)爲控制點,(x3,y3)爲終點。

總結

爲了弄清貝塞爾曲線是個什麼東西,和動畫曲線、速度又有什麼關聯,做者跑去複習了一下那些早扔給老師的東西,有說錯的請輕拍/(ㄒoㄒ)/~~

github.com/hujiulong/b…

相關文章
相關標籤/搜索