Android利用Flutter實現(xiàn)立體旋轉(zhuǎn)效果
前言
之前我們提到了 CustomPaint er 的 Paint 可以使用漸變(GradientShader)來填充繪制的圖形,本篇我們來介紹使用圖片填充,并且配合動畫實現(xiàn)“立體”旋轉(zhuǎn)效果,之所以給“立體”加上引號,是因為實際是通過填充圖片自身的光影效果旋轉(zhuǎn)后看起來像是立體效果一樣。下面是實現(xiàn)的效果圖。

ImageShader 簡介
ImageShader 的定義如下,我們來看看各個參數(shù)的用途。
image:用于填充的圖像,是Image類,注意這個Image類定義在dart:ui庫中,并不是我們用于構(gòu)建圖像組件的Widget下面的Image類。tmx:圖形在 x 軸的處理方式,即當被填充的寬度與圖片寬度不匹配時,在橫軸方向如何填充。tmy:圖形在y 軸的處理方式,即當被填充的高度與圖片高度不匹配時,在縱軸方向如何填充。matrix4:對填充圖像的三維空間的平移、旋轉(zhuǎn)等變換操作。filterQuality:當圖片尺寸和被填充圖形的尺寸不一致時,采樣的質(zhì)量,有高(high)、中 (medium)、低(low)三類。
ImageShader(
Image image,
TileMode tmx,
TileMode tmy,
Float64List matrix4,
{
FilterQuality? filterQuality,
}
)
tmx 和 tmy 是 TileMode 枚舉,有以下幾種取值:
clamp:圖片不能完整填充圖形時,使用最接近圖形邊緣的顏色進行填充,其實就是邊緣的延伸。比如同時這是 tmx 和 tmy 都為 TileMode.clamp 的時候的效果圖如下。

repeated:這個好理解,就是在各自方向重復(fù)。

decal:就是這個方向不做任何處理,使用透明填充,比如我們將上面的 tmy 改成 decal,就只會在 x 軸重復(fù)了。

mirror:顧名思義,就是鏡像填充,下面是 tmx 為 mirror,tmy 為 repeated的效果圖。

構(gòu)建 ui.Image對象
要使用 ImageShader,我們首先要從圖片資源中構(gòu)建ui.Image 對象。這需要將圖片文件按ByteData 二進制方式讀取,在將二進制文件解碼成為 ui.Image 對象。這個操作是異步的,因此在操作沒完成前不能使用圖像資源,我們設(shè)置了一個isImageLoaded布爾值標識圖像是否加載完成。
final ByteData data = await rootBundle.load('images/beauty.jpg');
fillImage = await loadImage(Uint8List.view(data.buffer));
Future<ui.Image> loadImage(Uint8List img) async {
final Completer<ui.Image> completer = Completer();
ui.decodeImageFromList(img, (ui.Image img) {
setState(() {
isImageLoaded = true;
});
return completer.complete(img);
});
return completer.future;
}
使用 ImageShader 填充形狀
使用 ImageShader 填充和 GradientShader 類似,按我們上面說的參數(shù)構(gòu)建一個 ImageShader 對象就可以了,代碼如下。注意,Paint 對象的填充方式必須是 fill,如果是空心的話是看不到效果的。
@override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.style = PaintingStyle.fill;
paint.shader = ImageShader(
image,
TileMode.mirror,
TileMode.repeated,
Matrix4.identity().storage,
filterQuality: FilterQuality.high,
);
canvas.drawRect(Rect.fromLTRB(0, 0, size.width, size.height), paint);
}
立體旋轉(zhuǎn)效果實現(xiàn)
立體效果需要利用填充圖像的光影效果,因此我們需要找一張圖片,比如明暗不同,或色彩不同的,這樣旋轉(zhuǎn)起來就會感覺是立體的。旋轉(zhuǎn)的話使用 Matrix4的旋轉(zhuǎn)變換就行。同時,為了讓旋轉(zhuǎn)過程展示的圖像不固定,我們旋轉(zhuǎn)的時候可以通過Matrix4的平移顯示不同圖形的區(qū)域。下面是我們用于測試的兩張圖片。


實現(xiàn)的代碼如下所示,其中animationValue是動畫過程中 Animation 對象的值,我們的動畫時長設(shè)置為10秒。這里我們繪制的其實是一個圓形,只是因為填充圖像在不停的旋轉(zhuǎn),且展示的圖像不同就看起來有了立體效果。
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.style = PaintingStyle.fill;
paint.shader = ImageShader(
image,
TileMode.mirror,
TileMode.mirror,
(Matrix4.identity()
..translate(5 * animationValue, 5 * animationValue)
..scaled(0.5)
..rotateZ(2 * pi * animationValue))
.storage,
filterQuality: FilterQuality.high,
);
Offset center = Offset(size.width / 2, size.height / 2);
canvas.drawCircle(center, 200, paint);
}
下圖是換了星球圖片的運行效果,大家也可以調(diào)整 ImageShader 的參數(shù)看看其他參數(shù)的效果。

總結(jié)
源碼已經(jīng)提交至:繪圖相關(guān)源碼,文件名為:image_shader_demo.dart。本篇介紹了 Flutter 繪圖使用 ImageShader 填充圖形,并且利用 Matrix4的三維變換加上動畫實現(xiàn)了立體旋轉(zhuǎn)的動畫效果。隨著對 Flutter 繪圖的深入,我們會發(fā)現(xiàn)繪圖覆蓋的面非常廣,也能夠?qū)崿F(xiàn)更多有趣的效果。
以上就是Android利用Flutter實現(xiàn)立體旋轉(zhuǎn)效果的詳細內(nèi)容,更多關(guān)于Android Flutter立體旋轉(zhuǎn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android控件PullRefreshViewGroup實現(xiàn)下拉刷新和上拉加載
這篇文章主要為大家詳細介紹了Android控件PullRefreshViewGroup實現(xiàn)下拉刷新和上拉加載效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
Android 沉浸式改變小米魅族狀態(tài)欄顏色的實例代碼
這篇文章主要介紹了Android 沉浸式改變小米魅族狀態(tài)欄顏色的實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02
Flutter Android應(yīng)用啟動白屏的解決方案
任何一個app基本都會設(shè)計一個啟動頁,今天我們就來看看怎么在flutter項目中設(shè)置啟動頁,這篇文章主要給大家介紹了關(guān)于Flutter Android應(yīng)用啟動白屏解決的相關(guān)資料,需要的朋友可以參考下2021-11-11
Android onSaveInstanceState和onRestoreInstanceState觸發(fā)的時機
這篇文章主要介紹了Android onSaveInstanceState和onRestoreInstanceState觸發(fā)的時機的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android ContentProvider獲取手機聯(lián)系人實例
這篇文章主要介紹了Android ContentProvider獲取手機聯(lián)系人實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02

