Flutter矢量图SVG的区域填色怎么实现

其他教程   发布日期:2025年02月20日   浏览次数:395

本文小编为大家详细介绍“Flutter矢量图SVG的区域填色怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Flutter矢量图SVG的区域填色怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

具体步骤: 1.SVG实际上就是一个xml文件,通过flutter自带的package xml进行进行图层解析 import 'package:xml/xml.dart';

这里是解析的部分代码

  1. Future<void> load() async {
  2. draws.clear();
  3. colors.clear();
  4. actualColors.clear();
  5. String assetName = 'lib/1057.svg';
  6. String svg = await rootBundle.loadString(assetName);
  7. final document = XmlDocument.parse(svg);
  8. final svgRoot = document.rootElement;
  9. Iterable<XmlElement> pathNodes = svgRoot.findAllElements('path');
  10. List<XmlElement> pathNodesList = pathNodes.toList();
  11. RegExp colorRegex = RegExp(r"#w{6}");
  12. for (int i = 0; i < pathNodesList.length; i++) {
  13. XmlElement element = pathNodesList[i];
  14. String? d = element.getAttribute('d');
  15. final Path path = parseSvgPathData(d ?? '');
  16. draws.add(path);
  17. String? style = element.getAttribute('style');
  18. assemblyColor(colorRegex, style);
  19. }
  20. setState(() {});
  21. }

2.绘制到canvas上:解析完成后,就是绘制呀 这里是绘制的代码

  1. class MyPainter extends CustomPainter {
  2. @override
  3. void paint(Canvas canvas, Size size) {
  4. for (int i = 0; i < draws.length; i++) {
  5. Path path = draws[i];
  6. canvas.drawPath(path, Paint()..color = colors[i]);
  7. }
  8. }
  9. Future<void> onTap(Offset offset) async {
  10. for (int i = 0; i < draws.length; i++) {
  11. Path path = draws[i];
  12. if (path.contains(offset)) {
  13. colors[i] = actualColors[i];
  14. return;
  15. }
  16. }
  17. }
  18. @override
  19. bool shouldRepaint(CustomPainter oldDelegate) => true;
  20. }

3.容器缩放:绘制完成后,一定要缩放啊 不然小小的多不开心 这里是容器的代码

  1. @override
  2. Widget build(BuildContext context) {
  3. var width = MediaQuery.of(context).size.width;
  4. return InteractiveViewer(
  5. boundaryMargin: const EdgeInsets.all(50),
  6. maxScale: 6,
  7. child: OverflowBox(
  8. child: GestureDetector(
  9. onTapDown: (TapDownDetails details) {
  10. Offset offset = Offset(
  11. details.localPosition.dx / (width / size.width),
  12. details.localPosition.dy / (width / size.width));
  13. _painter.onTap(offset);
  14. setState(() {});
  15. // 在这里处理点击事件
  16. },
  17. child: Container(
  18. color: Colors.white,
  19. width: width,
  20. height: width,
  21. child: Center(
  22. child: Transform.translate(
  23. offset: Offset(
  24. -(size.width - width) / 2.0 * (width / size.width),
  25. -(size.width - width) / 2.0 * (width / size.width)),
  26. child: Transform.scale(
  27. scale: width / size.width,
  28. child: RepaintBoundary(
  29. child: CustomPaint(
  30. isComplex: true,
  31. size: Size(size.width, size.width),
  32. painter: MyPainter(),
  33. ),
  34. ),
  35. ),
  36. ),
  37. ),
  38. ),
  39. ),
  40. ),
  41. );
  42. }
  43. }

4.动画:如此看来现在点击填充的时候是不是有个动画就更好了?

  1. class _FillWidgetState extends State<FillWidget>
  2. with SingleTickerProviderStateMixin {
  3. @override
  4. void initState() {
  5. _animationController = AnimationController(
  6. duration: const Duration(milliseconds: 500), vsync: this)
  7. ..repeat(reverse: true)
  8. ..addStatusListener((status) {
  9. if (status == AnimationStatus.completed) {
  10. print("Animation completed");
  11. setState(() {});
  12. } else if (status == AnimationStatus.dismissed) {
  13. print("Animation dismissed");
  14. }
  15. });
  16. _radiusAnimation =
  17. Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
  18. load();
  19. super.initState();
  20. }
  21. child: AnimatedBuilder(
  22. animation: _animationController,
  23. builder: (BuildContext context, Widget? child) {
  24. return RepaintBoundary(
  25. child: CustomPaint(
  26. key: UniqueKey(),
  27. isComplex: true,
  28. size: Size(size.width, size.width),
  29. painter: _painter,
  30. ),
  31. );
  32. },
  33. )

以上就是Flutter矢量图SVG的区域填色怎么实现的详细内容,更多关于Flutter矢量图SVG的区域填色怎么实现的资料请关注九品源码其它相关文章!