- 原文地址:Make 3D flip animation in Flutter
- 原文作者:Hung HD
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:ALVINYEH
- 校對者:geniusq1981
從 UI 挑戰中學習 Flutter
作為我的第一篇文章的續篇,我將開始新的挑戰。這個將比前一個(微光閃爍)複雜一點。我稱之為翻轉動畫:
這已經足夠值得挑戰了,不是嗎?是的,我們將製作一個看起來有些類 3D 效果的動畫。
怎麼做呢
乍一看,有個很簡單的想法:我們有一堆皮膚,每個皮膚被分成兩半,每一半可以圍繞 X 軸旋轉並顯示下一個皮膚。
如何用程式碼實現呢?我把它分為了兩個小任務:
- 將皮膚分割為兩半
- 圍繞 X 軸旋轉一半皮膚
那麼 Flutter 如何幫助我們呢?檢視 Flutter 文件,我發現有兩個元件非常適合完成任務:ClipRect 和 Transform。
實現
- 將皮膚分割為兩半:
ClipRect 元件有一個 clipper 引數來定義裁剪矩形的大小和位置,但是文件建議另一種使用 ClipRect 的方法:將它與 Align 一起使用:
class FlipWidget extends StatelessWidget {
Widget child;
FlipWidget({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: child,
)),
Padding(
padding: EdgeInsets.only(top: 2.0),
),
ClipRect(
child: Align(
alignment: Alignment.bottomCenter,
heightFactor: 0.5,
child: child,
)),
],
);
}
}
複製程式碼
嘗試一下:
就是這樣。此外,child 可以讓我們隨心所欲設計動畫的內容(無論如何是文字,還是影象)。
- 圍繞 X 軸旋轉一半皮膚
Transform 元件有一個 transform 引數,型別是 Matrix4,用於定義所應用的變換型別。Matrix4 暴露了一個名為 rotationX() 的工廠建構函式,看起來是我們需要用的,讓我們嘗試一下用在皮膚的上半部分:
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Transform(
transform: Matrix4.rotationX(pi / 4),
alignment: Alignment.bottomCenter,
child: ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: child,
)),
),
...
],
);
}
複製程式碼
嘗試一下:
什麼!!!!它看起來像放縮效果,不是嗎?
到底怎麼回事呢?回答出這個問題是這個任務中最難的一點。我回看 Flutter 的文件、示例程式碼、文章……直到找到這篇文章。其中指出,改變 Matrix4 的第 3 行和第 2 列的值,會改變其視角,並且會給變形帶來 3D 效果:
...
Transform(
transform: Matrix4.identity()..setEntry(3, 2, 0.006)..rotateX(pi / 4),
alignment: Alignment.bottomCenter,
child: ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: child,
)),
),
...
複製程式碼
再試一下:
不錯。但是不如試一下神奇的數字 0.006?說實話,我不知道如何準確計算它,只是嘗試選個我感覺很好的一些值。
剩下的就是為我們的元件新增動畫。這裡有一點點棘手。實際上,每個皮膚都有兩面(正面和背面)的內容,但是在程式碼中實現它並不明智,因為同一時刻只能看到一面。我假設要建立一個皮膚向上翻轉的動畫,那麼動畫可以分解成連續的兩個階段(順序),第一個是向上翻轉下半部分以使動畫顯示下一個皮膚的下半部分,然後隱藏當前皮膚的下半部分,第二個是在同一方向翻轉上半部分,以顯示下一半的上半部分,同時隱藏當前的上半部分:
這個動畫實現的程式碼很長,在此處插入並不太好。你可以在本文底部的連結中找到它。這是我們的最終效果:
真棒。我們剛剛用 Flutter 完成了另一個 UI 挑戰。熟能生巧。我會繼續尋找新的挑戰,使用 Flutter 解決它,並與你分享結果。感謝閱讀。
P/S:透視變換出現了個小問題(會導致變換後的影象偏斜),我在 rotateX() 中使用一個非常小的值而不是零,可以暫時解決這個問題。
完整程式碼: gist.github.com/hnvn/f1094f…
我已將我的程式碼釋出,包名為 flip_panel
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。