Flutter?繪制風車實現示例詳解
前言展示
最近源碼看得比較多,本文來畫點東西調節(jié)下心情,本繪制已收錄于 FlutterUnit 的繪制集錄,本文源碼可參見【windmill.dart】 。繪制內容非常簡單,如下所示,兩個樣式的小風車:通過這兩個小例子,可以學到:
路徑的使用
畫板的旋轉變換
動畫曲線與 Tween 的使用
風車1

風車2

動圖效果

1. 風車 1 的繪制
第一個風車非常簡單,由四個 半圓 組成,每個部分直接的關系是旋轉 90° 。如下所示, 通過 Path#addArc 添加一個半圓形的圓弧路徑。這樣就完成了一個單體:

@override
void paint(Canvas canvas, Size size) {
canvas.translate(size.width / 2, size.height / 2);
double d = size.width * 0.4;
Path path = Path()
..addArc(
Rect.fromCenter(center: Offset(d / 2, 0), width: d, height: d),
0,
pi,
);
Paint paint = Paint()..color = const Color(0xffFBBD19);
canvas.drawPath(path, paint);
}
接下來只需要在此基礎上,將畫板旋轉 90° 換個顏色再畫一次這個路徑即可。你可以想象一下,你在一張紙上畫了如下的黃色塊,然后把紙沿中心旋轉 90°,只要再繪制和剛才同樣的圖形即可:

canvas.rotate(pi / 2); canvas.drawPath(path, paint..color = const Color(0xff30A04C));
以此類推,畫一個轉 90° ,畫 4 此即可。如下所示,可以通過 colors 列表通過循環(huán)遍歷繪制。這樣一個簡單的小風車就躍然紙上了,從這里可以看出,只要更改單體的路徑,即可完成不同樣式的小風車。

List<Color> colors = const [
Color(0xffE74437), Color(0xffFBBD19),
Color(0xff3482F0), Color(0xff30A04C)
];
Paint paint = Paint();
for (Color color in colors) {
canvas.drawPath(path, paint..color=color);
canvas.rotate(pi / 2);
}
2. 風車 2 的繪制
風車 2 的繪制是有一定難度的,首先期望繪制是具有 矢量性 的,它會隨著 畫板 的大小自適應尺寸。也就是說,我們繪制時使用的尺寸都要以畫布的尺寸為基準。

其次,難點在于數據信息,這方面可以通過 PhotoShop 等軟件來量取尺寸,獲取關鍵點坐標,然后進行按照比例來進行路徑操作。好在這里只需要獲取一個單體坐標信息,其他三個旋轉遍歷即可。

每個單體中由兩塊區(qū)域組成,分別通過路徑的點操作即可。在實際開發(fā)中,如果設計給了一些比較規(guī)整的圖形,需要繪制的話,也可以采用類似的方法,或者讓設計幫你量好關鍵點的坐標,你按比例換算即可。
@override
void paint(Canvas canvas, Size size) {
List<Color> colors = const [ Color(0xffE74437), Color(0xffFBBD19), Color(0xff3482F0), Color(0xff30A04C) ];
canvas.translate(size.width / 2, size.height / 2);
double d = size.width * 0.4;
canvas.rotate(rotate.value*2*pi);
Paint paint = Paint();
for (Color color in colors) {
Path path1 = Path()
..moveTo(0, -d * 46/203)
..lineTo(0, -d * 203/203)
..lineTo(102/203 * d, -102/203 * d)
..lineTo(12/203 * d, -12/203 * d)..close();
canvas.drawPath(path1, paint..color=color);
Path path2 = Path()
..moveTo(12/203 * d, -12/203 * d)
..lineTo(102/203 * d, -102/203 * d)
..lineTo(102/203 * d, 0 )
..lineTo(46/203 * d, 0 )..close();
canvas.drawPath(path2, paint..color=color.withOpacity(0.2));
canvas.rotate(pi / 2);
}
}
3. 旋轉動畫的處理
Flutter 中的動畫非常簡單,首先創(chuàng)建 AnimationController 作為動畫的 "驅動器";然后如需曲線變換,可以使用 CurveTween 控制數值運動的速度,比如這里使用 Curves.easeIn 先慢后快:

class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
late final AnimationController _ctrl = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
);
late Animation<double> rotate;
@override
void initState() {
rotate = CurveTween(curve: Curves.easeIn).animate(_ctrl);
super.initState();
}
最后將 Animation<double> 對象傳入 WindmillPainter 畫板中,作為畫板繪制的驅動力,在繪制前根據數值對畫布進行旋轉即可:

4. 旋轉動畫的圈數
可能有人發(fā)現,這點一下就轉一圈,如何轉多圈呢?其實這就是一個數學問題:轉一圈是 360°,想轉 n 圈,本質上就是在規(guī)定時間內旋轉 n*360°。 這通過 Tween 是很容易實現的:

比如這里轉 3 圈,最核心的是通過 Tween 指定一個 補間 ,然后這個 rotate 在動畫進行時就會從 0 運動到 3*2*pi。繪制時畫板旋轉 rotate.value 即可。

canvas.rotate(rotate.value);
本案例已加入 FlutterUnit的繪制集錄,可在下版本更新后體驗,感謝支持 FlutterUnit。
這就是一個非常簡單的繪制與動畫結合的小例子,希望可以對剛接觸的繪制的朋友有所幫助。不僅是 Flutter 其他的框架只要有畫板,只要能有動畫驅動,都可以完成類似的繪制,更多關于Flutter 繪制風車的資料請關注腳本之家其它相關文章!
相關文章
Android ScrollView嵌套ExpandableListView顯示不正常的問題的解決辦法
這篇文章主要介紹了Android ScrollView嵌套ExpandableListView顯示不正常的問題的解決辦法的相關資料,需要的朋友可以參考下2017-02-02
Android Studio連接MySql實現登錄注冊(附源代碼)
登錄注冊是常用的一個功能,正好今天用android studio 做一個類似于這樣的登錄軟件,需要的朋友們下面隨著小編來一起學習學習吧2021-05-05

