Flutter 動畫詳解(一)

本文主要介紹了動畫的原理相關概念,對其餘平臺的動畫作了一個簡要的梳理,並簡要的介紹了Flutter動畫的一些知識。css

1. 動畫介紹

動畫對於App來講,很是的重要。不少App,正是由於有了動畫,因此纔會以爲炫酷。移動端的動畫庫有很是的多,例如iOS上的Pop、web端的animate.css、Android端的AndroidViewAnimations、跨平臺的Lottie等。正是由於有了這些封裝好的動畫庫,咱們製做酷炫的效果方便了很多。固然了,這些庫都是基於各平臺基礎的動畫API實現的,筆者今天要聊的,也就是基礎的動畫及背後的原理。html

1.1 動畫的本質

動畫顧名思義,就是動起來的畫面。畫面爲何會動起來了呢?在回答這個問題以前,咱們先引入一個概念。git

人眼在觀察景物時,光信號傳入大腦神經,需通過一段短暫的時間,光的做用結束後,視覺形象並不當即消失,這種殘留的視覺稱「後像」,視覺的這一現象則被稱爲「視覺暫留」。github

視覺暫留被認爲是電影的最重要的一個理論基礎。咱們看到的動畫,其實是一連串的畫面組成,只不過是以很快的速度去播放,人眼在下一個畫面出來以前,還殘留着上一個畫面的視覺,看起來就像是在沒有間隔的播放這一系列的圖片,也就是咱們稱之爲的動畫。web

1.2 相關概念

動畫會有不少相關的概念,理解了這些概念,會對實際的使用更有幫助。canvas

1.2.1 幀

剛纔在介紹動畫本質的時候,用到了畫面這個詞彙,只是方便讀者去理解,這個畫面,在學術上叫作bash

幀就是影像動畫中最小單位的單幅影像畫面,一幀就是一副靜止的畫面。框架

幀

幀裏面又分爲關鍵幀和過渡幀,這兩概念是理解一些動畫的基礎,例如Android中的補間動畫。在一些場景中,咱們可能不會給出一個動畫的全部幀,因此將幀分紅關鍵幀和過渡幀。關鍵幀能夠理解爲一個動畫的起始狀態,而過渡幀則是系統自動完成插在關鍵幀之間的部分。函數

關鍵幀與過渡幀

咱們知道Android中的補間動畫,基礎的有四種類型,平移、縮放、旋轉、透明度。而咱們設置動畫的時候,一般只是設置起始的狀態,也就是關鍵幀,中間過程其實咱們並不須要去考慮,若是關注動畫速率的話,頂多加一個差值器去控制,可是中間生成的幀咱們並無提供。學習

系統爲何可以補齊過渡幀呢?咱們看下這四種基本的動畫類型,給定起始狀態,中間狀態咱們實際上是能夠經過計算推演出來的,這也是系統爲何可以補齊的緣由。

是否是隻有這四種才能夠經過系統填補過渡幀呢?顯然不是的,例如一個跳躍前進的動畫,添加一些限制條件,就能夠推演出中間的狀態。系統提供的只是比較常見的四種,並非說只有這四種,而是絕大部分動畫均可以經過這四種組合實現。固然了,確定也是有實現不了的,這個時候有一個辦法就是經過canvas畫出來。

另外再插一嘴,Android系統提供的四種動畫操做,也是變換矩陣是四維的緣由,具體的就很少說了,以前文章也有介紹過。

最後一嘴,此處講解幀的概念,拿了不少Android相關的知識去講解,只是但願讀者可以經過一些已知的概念,去理解一些未知的。動畫的原理都同樣,具體到某個平臺,可能頂多就是實現或者叫法不同罷了。

1.2.2 幀數與FPS

小時候不少人都玩過書角動畫。在書或者本子的一角,每一頁都畫上一個畫面,而後撥書角,不一樣速度撥,動畫的感覺不同,撥的越快,動畫越流暢。這是爲何呢?這就牽扯到幀數與FPS了。

幀數,幀的數量。FPS(Frame per Second),即每秒顯示幀數。

這兩個概念,主要是FPS有什麼做用呢?這是由於人眼生理構造的緣由。人眼殘留鏡像的時間是有限的,若是過了這個時間,下一幀尚未變化,就會感受不流暢。但也不是幀數越大越好,畢竟人眼也是有極限的。

幀數不一樣的感受

1.2.3 插值器

若是動畫播放一直都是這種勻速的進行,那表現形式就太單一了。那如何實現非線性的動畫效果呢,這個時候就須要用到插值器了。

插值器其實並不複雜,就是一個數學函數,設置屬性值從初始值過渡到結束值的變化規律。每一個平臺都有本身定義好的一系列插值器,能夠供開發者選擇使用,也提供自定義的接口,本質上是一個貝塞爾函數。

一個勻速插值器以下:

屬性值百分比 = 時間百分比
複製代碼

1.3 如何實現

動畫的基本原理和一些基本概念都介紹了一下,如今來聊一下動畫的實現。

先拋開系統層級的各類渲染優化,也僅僅是以補間動畫爲例,假設以現有的移動平臺基礎上,去實現一套簡單的動畫框架,該如何去實現呢?

以Android的爲例,要實現平移、縮放、旋轉、透明度這四種基礎的補間動畫,能夠看到,這些都是基於某個屬性的動畫,平移是基於point、縮放是基於scale、旋轉是基於angle、透明度是基於alpha。

結合插值器,提煉出一個通用的動畫類,這個類的做用是根據插值器,獲得視圖某個時間點的屬性變化的狀態。

既然各個時間點的狀態已經有了,剩下來的就是讓各個狀態渲染出來。底層的機制在此處不去討論,這個地方就須要一個定時器,定時器的做用是每隔一段時間就把素材渲染到屏幕上。

至此,一個簡易的動畫框架就出來了。若是對各平臺比較瞭解的話,就知道我說的是視圖動畫,真正的動畫引擎不是這麼簡單,涉及到的技術也比較複雜,可是大致的思想不會有錯,無論是哪一種動畫,都是跟時間相關的幀序列,只是實現方式不一樣。

這也是筆者爲何花這麼多篇幅去介紹動畫相關的概念,知道一些底層原理後,無論什麼平臺,怎麼去實現,底層的思想確定都差很少,只是實現上的不一樣。

2. 其餘平臺的動畫

Flutter動畫,與Android、iOS等平臺對比,其實自己並無什麼特別之處。基本的原理是同樣的,只是提供的種類以及實現的方式不一樣罷了。

2.1 Android動畫

Android的動畫,大的分類有兩種:

  • 視圖動畫(View Animation)
  • 屬性動畫(Property Animation)

視圖動畫又能夠分爲兩類:

  • 補間動畫(Tween Animation)
  • 逐幀動畫(Frame Animation)

這之間的差異是什麼呢?它們只有實現上的差異

  • 補間動畫是根據初始狀態,系統自動補充中間狀態;
  • 逐幀動畫則是須要咱們提供每一幀;
  • 視圖動畫只是做用於視圖上,而不會改變控件的屬性;
  • 屬性動畫則是會實實在在的更改控件的屬性。

能夠看出Android的動畫分類仍是比較明晰的。

2.2 iOS動畫

iOS好久沒弄了,在這裏也簡單說下,不對的話還請各位指正。

  • 隱式動畫
  • 顯式動畫

顯式動畫又能夠分爲兩類:

  • 基礎動畫
  • 關鍵幀動畫

這些動畫類別之間的差異是什麼呢?

  • 隱式動畫,顧名思義是不指定動畫類型,更改某個屬性,Core Animation來決定如何且什麼時候去作動畫;
  • 基礎動畫,根據起始值來作動畫;
  • 關鍵幀動畫,則是定義一系列關鍵幀,系統自動補齊中間的過渡幀。

經過動畫這一起,能夠看出iOS的分類實際上是比較的模糊的,有一些歷史包袱。

2.3 css動畫

css動畫大致上有兩種:

  • Transition
  • Animation

web中的動畫分類簡單的多了

  • Transition動畫,給定起始值,能夠結合插值器作動畫;
  • Animation動畫,則是定義一系列關鍵幀,系統補齊中間的過渡幀。

2.4 小節

經過上面個平臺動畫粗略的介紹,動畫在不一樣平臺雖然被叫着不一樣的名稱,本質上其實都差很少的,變來變去都是這幾種方式,要麼根據屬性要麼根據關鍵幀,要麼更改繪製層,要麼更改控件自己屬性。一些遊戲引擎,雖然我沒有看,可是我以爲原理也大體類似。

3. Flutter動畫

上面鋪墊了這麼多,終於到Flutter動畫了。Flutter是一門比較新的技術,歷史包袱理應說是最小的。

3.1 Flutter動畫分類

Flutter動畫分爲兩類:

  • 補間動畫(Tween Animation)
  • 基於物理的動畫(Physics-based animation)

補間動畫很好理解,基於物理的動畫是這個什麼鬼。

基於物理的動畫是一種遵循物理學定律的動畫形式

舉個例子,比方說你滑動一張圖片,這個過程不是勻速的,而是起始速度快,而後慢慢的降速,就像一本書在地上往前推同樣。它有什麼特色呢?

  • 遵循物理學定律;
  • 可以依據加速度和速度去計算和更新每一幀的動畫數值;
  • 當受力平衡時,動畫爲處於恆定運動或靜止狀態。

哈哈,最後一點是否是似曾相識,這樣作的好處是什麼呢?隨着人們生活水平的極大提高,移動端硬件這些年也是趕英超美,人們再也不知足於簡單的動畫,因而就有部分有(xian)識(de)之(dan)士(teng),實現了基於物理學定律的動畫。

這種動畫iOS或者Android有沒有呢,是有的,但不是做爲最基礎的動畫API被提供。爲何其餘平臺沒有將這個歸入最基本的動畫中去呢?

  • 歷史緣由。iOS以及Android端多年前就誕生了,那個時候,硬件資源都是極其有限的,當時的環境不足以支撐這種動畫效果。但也不是說沒有,一些遊戲引擎裏面也是有的,可是做爲操做系統,把這些集成進去,仍是不太現實的。
  • 認知過程。電腦以及移動端這些年的發展,最開始只是知足於查看最簡單的文本,而後各類圖片視頻。隨着互聯網的愈來愈普及,人們的需求愈來愈多了。因而,在一些遊戲裏面纔會見到的基於物理學定律的動畫,進入了尋常百姓家。反觀一下,如今也是有很是多的「委屈」事物。例如人類幾千年都是經過人眼看現實的事物,如今卻被限制在一個小屏幕上,這實際上是不合理的。因此AR、VR,還有一些動畫片科幻片中的遠程感知等技術,纔會層出不窮,固然這個扯的有些遠了。

基於物理的動畫這麼好,那有什麼好處呢?更天然,更加符合人們的認知。

3.2 分類的緣由

前面講的各平臺的動畫,從本質上看,基於某個屬性也好,幀動畫也好,都是從一種狀態到另外一種狀態,而中間過程是能夠推演出來的,因此Flutter提供補間動畫。

基於物理的動畫,我猜想多是爲了實現其餘平臺上的一些效果,例如彈簧、阻尼效果等等。因此Flutter就提供了這種動畫API,畢竟沒什麼包袱。

3.3 動畫模式

Flutter提煉了三種動畫模式,與其說提煉出來的,倒不如說統一不能更爲合適。

  • list、grid中的動畫(Animated list or grid)。場景是item的添加或者刪除操做;
  • 轉場動畫(Shared element transition)。場景是當前頁面打開另外一頁面的過渡動畫;
  • 交錯動畫(Staggered animation)。場景是須要部分或者徹底交錯的動畫。

3.4 複雜度

Flutter的實現原理以及這個階段,註定了作動畫是很是麻煩的一件事情。跨平臺的技術作動畫都麻煩,這個彷佛是通識,爲了跨平臺而同化的一些東西,到異化部分,就變得蛋疼了,動畫正是這種存在。

Flutter作動畫複雜體如今哪些地方呢?

  • 實現的動畫較少,這個是初期,沒啥好說的;
  • 動畫實現的方式複雜,這個是Flutter的設計思想所決定的。

4. 小節

關於動畫的具體的實現、一些底層的代碼邏輯以及如何使用,將會在下一篇文章中作介紹。這篇文章更多的是偏於一些普適性的介紹,關於Flutter動畫相關的介紹反而不多。但願讀者可以瞭解一些動畫的原理,以及各個平臺動畫的大體實現方式,這樣能夠更好的理解Flutter動畫的設計思想。文中如有錯誤的地方,還懇請指出,在此不勝感激。

5. 後話

筆者建了一個Flutter學習相關的項目,Github地址,裏面包含了筆者寫的關於Flutter學習相關的一些文章,會按期更新,也會上傳一些學習Demo,歡迎你們關注。

6. 參考

  1. 電影原理
  2. 視覺暫留
  3. iOS-Core-Animation-Advanced-Techniques
  4. CSS動畫簡介
  5. Animations in Flutter
  6. Android 中基於物理特性的動畫簡介
相關文章
相關標籤/搜索