Flutter SVG图片Demo
欢迎大家加入开源鸿蒙跨平台社区
Flutter SVG 图片 Demo
本文介绍在 Flutter(鸿蒙跨平台)项目中不依赖任何第三方库,使用纯 Dart +CustomPainter实现 SVG 图形渲染、属性编辑、动画播放的核心要点。
一、方案选择:纯 Dart 替代 flutter_svg
flutter_svg等主流 SVG 插件在鸿蒙平台存在兼容问题,因此采用CustomPainter直接绘制矢量图形,实现零依赖、完全跨平台。
class_ShapePainterextendsCustomPainter{finalvoidFunction(Canvas,Size)draw;_ShapePainter(this.draw);@overridevoidpaint(Canvascanvas,Sizesize)=>draw(canvas,size);@overrideboolshouldRepaint(_)=>false;}将绘制逻辑作为函数传入,实现高度复用。
二、整体结构
使用IndexedStack+NavigationBar实现三 Tab 布局:
body:IndexedStack(index:_tabIndex,children:const[_GalleryTab(),_EditorTab(),_AnimTab()],),三、常用 SVG 图形绘制
星形(多边形路径)
通过奇偶半径交替计算顶点绘制星形:
Path_starPath(double cx,double cy,double outerR,double innerR,int points){finalpath=Path();for(int i=0;i<points*2;i++){finalr=i.isEven?outerR:innerR;finalangle=pi*i/points-pi/2;finalx=cx+r*cos(angle);finaly=cy+r*sin(angle);i==0?path.moveTo(x,y):path.lineTo(x,y);}returnpath..close();}心形(贝塞尔曲线)
使用cubicTo三次贝塞尔曲线构造心形轮廓:
path.moveTo(w*0.5,h*0.85);path.cubicTo(w*0.1,h*0.6,w*0.0,h*0.3,w*0.25,h*0.2);path.cubicTo(w*0.4,h*0.1,w*0.5,h*0.2,w*0.5,h*0.3);// 对称右侧...螺旋线(参数方程)
阿基米德螺旋:半径随角度线性增长:
for(int i=0;i<=steps;i++){finalt=i/steps;finalangle=t*turns*2*pi;finalr=t*maxRadius;// 半径线性增长finalx=cx+r*cos(angle);finaly=cy+r*sin(angle);i==0?path.moveTo(x,y):path.lineTo(x,y);}四、SVG 属性编辑器
通过Paint对象的参数实时控制填充、描边、透明度:
finalfill=Paint()..color=fillColor..style=PaintingStyle.fill;finalstroke=Paint()..color=strokeColor..style=PaintingStyle.stroke..strokeWidth=strokeWidth;配合Transform.rotate+Transform.scale+Opacity实现旋转、缩放、透明度的实时预览:
Opacity(opacity:_opacity,child:Transform.rotate(angle:_rotation*pi/180,child:Transform.scale(scale:_scale,child:CustomPaint(...)),),),五、SVG 动画
使用AnimationController+ 多个Tween驱动旋转、缩放、颜色动画:
_ctrl=AnimationController(vsync:this,duration:constDuration(seconds:2))..repeat(reverse:true);_rotateAnim=Tween(begin:0.0,end:2*pi).animate(_ctrl);_scaleAnim=Tween(begin:0.5,end:1.5).animate(_ctrl);_colorAnim=ColorTween(begin:Colors.blue,end:Colors.orange).animate(_ctrl);AnimatedBuilder监听动画值,按模式选择性应用变换:
AnimatedBuilder(animation:_ctrl,builder:(_,__){finalangle=(_animMode==0||_animMode==3)?_rotateAnim.value:0.0;finalscale=(_animMode==1||_animMode==3)?_scaleAnim.value:1.0;finalcolor=(_animMode==2||_animMode==3)?_colorAnim.value!:Colors.blue;returnTransform.rotate(angle:angle,child:Transform.scale(scale:scale,...));},),六、花瓣动画绘制
在CustomPainter中通过progress参数驱动花瓣旋转和圆弧进度:
for(int i=0;i<petalCount;i++){finalangle=2*pi*i/petalCount+progress*2*pi;// 随进度旋转canvas.drawCircle(Offset(cx+r*cos(angle),cy+r*sin(angle)),r*0.35,paint);}// 外圆弧进度canvas.drawArc(rect,-pi/2,2*pi*progress,false,arcPaint);总结
| 模块 | 核心技术 |
|---|---|
| 图形绘制 | CustomPainter+CanvasAPI |
| 路径构造 | Path.cubicTo/lineTo/ 参数方程 |
| 属性编辑 | Paint参数 +Transform+Opacity |
| 动画驱动 | AnimationController+Tween+AnimatedBuilder |
| 平台兼容 | 纯 Dart 实现,无需第三方插件,完全支持鸿蒙 |
