前言 实现UI和交互是大前端开发者的必备技能,也是掌握Flutter开发的重点;在下学习Flutter之际,实现了几种客户端上常见的酷炫UI特效,虽说是用Flutter造原生的轮子,但Flutter跨平台的特性是原生不能比拟的,更何况还有不弱的性能表现。本文主要是介绍Flutter特效库flutter_effects 的基本情况和使用;
项目介绍 flutter_effects :是多个Flutter package工程组成,目标是用纯Flutter来实现炫酷的UI特效,支持android
和ios
运行;目前项目刚处于起步阶段,欢迎大家提出建议和问题反馈,如果你有好的想法,欢迎提出需求或者一起参与进来;
已经实现的功能:
类型
支持子widget
备注
差字缩放
文本
仅支持字符,不支持富文本
边界线条
所有
-
彩虹字体
文本
当前仅支持文本,富文本待定
粒子爆炸
所有
支持所有widget,包括图片
狠狠砸地
所有
-
刮刮卡
所有
前景需要用canvas绘制
更多功能
-
开发中。。。
使用介绍 差字缩放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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
;
边界线条
1 2 3 4 5 6 LineBorderText( child: Text( "Border Effect" , style: TextStyle(fontSize: 20 ), ), autoAnim: true )
LineBorderText
支持任意widget作为child,参数autoAnim
控制创建时是否自动执行一遍动画;
彩虹字体
1 2 3 4 5 6 7 8 RainbowText(colors: [ Color(0xFFFF2B22 ), Color(0xFFFF7F22 ), Color(0xFFEDFF22 ), Color(0xFF22FF22 ), Color(0xFF22F4FF ), Color(0xFF5400F7 ), ], text: "Welcome to BBT" , loop: true )
RainbowText
暂时支持文字
的颜色变换,参数loop
控制是否循环执行动画;
粒子爆炸
1 2 3 4 5 6 7 8 9 10 11 12 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不会执行爆炸效果;
狠狠砸地
1 2 3 4 AnvilEffectWidget(child: Text( "👉AnvilEffect👈" , style: TextStyle(color: Colors.white, fontSize: 20 ), )
AnvilEffectWidget
支持任意类型的widget作为child;
刮刮卡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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
绘制前景涂层;
下一步计划
优化现有功能
: 当前功能我用一周的业余时间赶出来的,难免有不当之处,事不在多而在于精,优化性能和api调用可能是比较重要的;
提交到dart pub
:提交到pub肯定是便于使用的,在此之前还要对模块进行新的划分,可能要拆分成多个包提交;
事件的引入
:当前用rebuild的形式触发动画不算是巧妙的方式;
引入更多功能
:有好的效果,我愿一试;
致谢: 本项目实施过程中,部分灵感来自原生代码实现
:
Android粒子爆炸效果:https://github.com/tyrantgit/ExplosionField
Android酷炫TextView:https://github.com/hanks-zyh/HTextView
感谢上述项目作者hanks
和tyrantgit
,致谢!