前言
實現UI和互動是大前端開發者的必備技能,也是掌握Flutter開發的重點;在下學習Flutter之際,實現了幾種客戶端上常見的酷炫UI特效,雖說是用Flutter造原生的輪子,但Flutter跨平臺的特性是原生不能比擬的,更何況還有不弱的效能表現。本文主要是介紹Flutter特效庫flutter_effects的基本情況和使用;
專案介紹
flutter_effects:是多個Flutter package工程組成,目標是用純Flutter來實現炫酷的UI特效,支援android和ios執行;目前專案剛處於起步階段,歡迎大家提出建議和問題反饋,如果你有好的想法,歡迎提出需求或者一起參與進來;
已經實現的功能:
型別 | 支援子widget | 備註 |
---|---|---|
差字縮放 | 文字 | 僅支援字元,不支援富文字 |
邊界線條 | 所有 | - |
彩虹字型 | 文字 | 當前僅支援文字,富文字待定 |
粒子爆炸 | 所有 | 支援所有widget,包括圖片 |
狠狠砸地 | 所有 | - |
刮刮卡 | 所有 | 前景需要用canvas繪製 |
更多功能 | - | 開發中。。。 |
使用介紹
差字縮放
void initState() {
super.initState();
sentences = [
"What is design?",
"Design is not just",
"what it looks like and feels like.",
"Design is how it works. \n- Steve Jobs",
"Older people",
"sit down and ask,",
"'What is it?'",
"but the boy asks,",
"What can I do with it?. \n- Steve Jobs",
"Swift",
"Objective-C",
"iPhone",
"iPad",
"Mac Mini",
"MacBook Pro",
"Mac Pro",
"愛老婆",
"老婆和女兒"
];
}
DiffScaleText(
text: sentences[diffScaleNext % sentences.length],
textStyle: TextStyle(fontSize: 20, color: Colors.blue),
)
複製程式碼
DiffScaleText暫時只支援中英文字元,不支援表情和富文字; 引數text控制顯示文字,更新下一個只需要改變text然後rebuild即可,不需要手動儲存歷史text;
邊界線條
LineBorderText(
child: Text(
"Border Effect",
style: TextStyle(fontSize: 20),
),
autoAnim: true)
複製程式碼
LineBorderText支援任意widget作為child,引數autoAnim控制建立時是否自動執行一遍動畫;
彩虹字型
RainbowText(colors: [
Color(0xFFFF2B22),
Color(0xFFFF7F22),
Color(0xFFEDFF22),
Color(0xFF22FF22),
Color(0xFF22F4FF),
Color(0xFF5400F7),
], text: "Welcome to BBT", loop: true)
複製程式碼
RainbowText暫時支援文字的顏色變換,引數loop控制是否迴圈執行動畫;
粒子爆炸
ExplosionWidget(
tag: "Explosion Text",
child: Container(
alignment: Alignment.center,
color: Colors.blueAccent,
child: Text(
"Explosion Text",
style: TextStyle(
fontSize: 20,
color: Colors.red,
fontWeight: FontWeight.bold),
)))
複製程式碼
ExplosionWidget支援任意型別的widget作為child,注意引數tag表示child的唯一性,如果改變了child一定要改變tag,否則rebuild不會執行爆炸效果;
狠狠砸地
AnvilEffectWidget(child: Text(
"?AnvilEffect?",
style: TextStyle(color: Colors.white, fontSize: 20),
)
複製程式碼
AnvilEffectWidget支援任意型別的widget作為child;
刮刮卡
ScratchCardWidget(
strokeWidth: 20,
threshold: 0.5,
foreground: (canvas, size, offset) {
if (_image != null) {
double scale;
double dx = 0;
double dy = 0;
if (_image.width * size.height >
size.width * _image.height) {
scale = size.height / _image.height;
dx = (size.width - _image.width * scale) / 2;
} else {
scale = size.width / _image.width;
dy = (size.height - _image.height * scale) / 2;
}
canvas.save();
canvas.translate(dx, dy);
canvas.scale(scale, scale);
canvas.drawImage(_image, Offset(0, 0), new Paint());
canvas.restore();
} else {
canvas.drawRect(
Rect.fromLTWH(0, 0, size.width, size.height),
Paint()
..color = Colors.grey);
}
},
child: Container(
color: Colors.blueAccent,
alignment: Alignment.center,
child: Image.asset(
"assets/images/icon_sm_sigin_status_three.png",
fit: BoxFit.scaleDown, height: 20,),
))
複製程式碼
ScratchCardWidget引數較多,一個一個看:
- strokeWidth : 手觸的寬度;
- threshold : 觸發清除前景覆蓋物的臨界值,程式碼邏輯是計算全透明畫素的比例;
- foreground : 這個是Function型別,目的是繪製前景覆蓋物,也就是刮刮卡的塗層;
- child : 這個是刮刮卡的內容,支援任意widget作為child;
- (canvas, size, offset){}: foreground對應的Function型別,支援用canvas繪製前景塗層;
更多效果會持續更新,請關注flutter_effects;
下一步計劃
- 優化現有功能: 當前功能我用一週的業餘時間趕出來的,難免有不當之處,事不在多而在於精,優化效能和api呼叫可能是比較重要的;
- 提交到dart pub:提交到pub肯定是便於使用的,在此之前還要對模組進行新的劃分,可能要拆分成多個包提交;
- 事件的引入:當前用rebuild的形式觸發動畫不算是巧妙的方式;
- 引入更多功能:有好的效果,我願一試;
致謝:
粒子爆炸效果:github.com/tyrantgit/E…
酷炫TextView:github.com/hanks-zyh/H…
感謝原生實現庫作者hanks和tyrantgit,致謝!
作者:HitenDev 連結:www.jianshu.com/p/dcec5c4f1…
閱讀更多
Android App瘦身新姿勢——Android App Bundle
阿里:我為什麼禁止把SimpleDateFormat定義為static型別的?
最後如果對技術比較感興趣,歡迎關注我的微信公眾號:終端研發部,id:codeGooger,一起進階技術