本文小编为大家详细介绍“Flutter矢量图SVG的区域填色怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Flutter矢量图SVG的区域填色怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
具体步骤: 1.SVG实际上就是一个xml文件,通过flutter自带的package xml进行进行图层解析 import 'package:xml/xml.dart';
这里是解析的部分代码
Future<void> load() async { draws.clear(); colors.clear(); actualColors.clear(); String assetName = 'lib/1057.svg'; String svg = await rootBundle.loadString(assetName); final document = XmlDocument.parse(svg); final svgRoot = document.rootElement; Iterable<XmlElement> pathNodes = svgRoot.findAllElements('path'); List<XmlElement> pathNodesList = pathNodes.toList(); RegExp colorRegex = RegExp(r"#\w{6}"); for (int i = 0; i < pathNodesList.length; i++) { XmlElement element = pathNodesList[i]; String? d = element.getAttribute('d'); final Path path = parseSvgPathData(d ?? ''); draws.add(path); String? style = element.getAttribute('style'); assemblyColor(colorRegex, style); } setState(() {}); }
2.绘制到canvas上:解析完成后,就是绘制呀 这里是绘制的代码
class MyPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { for (int i = 0; i < draws.length; i++) { Path path = draws[i]; canvas.drawPath(path, Paint()..color = colors[i]); } } Future<void> onTap(Offset offset) async { for (int i = 0; i < draws.length; i++) { Path path = draws[i]; if (path.contains(offset)) { colors[i] = actualColors[i]; return; } } } @override bool shouldRepaint(CustomPainter oldDelegate) => true; }
3.容器缩放:绘制完成后,一定要缩放啊 不然小小的多不开心 这里是容器的代码
@override Widget build(BuildContext context) { var width = MediaQuery.of(context).size.width; return InteractiveViewer( boundaryMargin: const EdgeInsets.all(50), maxScale: 6, child: OverflowBox( child: GestureDetector( onTapDown: (TapDownDetails details) { Offset offset = Offset( details.localPosition.dx / (width / size.width), details.localPosition.dy / (width / size.width)); _painter.onTap(offset); setState(() {}); // 在这里处理点击事件 }, child: Container( color: Colors.white, width: width, height: width, child: Center( child: Transform.translate( offset: Offset( -(size.width - width) / 2.0 * (width / size.width), -(size.width - width) / 2.0 * (width / size.width)), child: Transform.scale( scale: width / size.width, child: RepaintBoundary( child: CustomPaint( isComplex: true, size: Size(size.width, size.width), painter: MyPainter(), ), ), ), ), ), ), ), ), ); } }
4.动画:如此看来现在点击填充的时候是不是有个动画就更好了?
class _FillWidgetState extends State<FillWidget> with SingleTickerProviderStateMixin { @override void initState() { _animationController = AnimationController( duration: const Duration(milliseconds: 500), vsync: this) ..repeat(reverse: true) ..addStatusListener((status) { if (status == AnimationStatus.completed) { print("Animation completed"); setState(() {}); } else if (status == AnimationStatus.dismissed) { print("Animation dismissed"); } }); _radiusAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_animationController); load(); super.initState(); } child: AnimatedBuilder( animation: _animationController, builder: (BuildContext context, Widget? child) { return RepaintBoundary( child: CustomPaint( key: UniqueKey(), isComplex: true, size: Size(size.width, size.width), painter: _painter, ), ); }, )
读到这里,这篇“Flutter矢量图SVG的区域填色怎么实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。