Flutter学习之矢量图SVG的区域填色示例详解

 更新时间:2023年04月14日 14:37:54   作者:小孙的Flutter  
这篇文章主要为大家介绍了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区域填色的资料请关注脚本之家其它相关文章!

相关文章

  • AndroidView与Compose框架交互实现介绍

    AndroidView与Compose框架交互实现介绍

    Android Compose自推出正式版本后,google 就一直推荐使用Compose来开发。正好疫情期间,作为一个 Android 摸鱼达人,就来摸索一下Compose的开发。说实话开发了2天感觉对Android 开发人员来说变化是巨大的,但是作为从业者我们还必须学习和学会,才能不被甩开
    2022-09-09
  • Flutter onTap中让你脱颖而出的5条规则

    Flutter onTap中让你脱颖而出的5条规则

    这篇文章主要为大家介绍了Flutter onTap中让你脱颖而出的5条规则,小事情决定了你的熟练程度,这些小细节的有趣之处在于它们的丰富性
    2023-11-11
  • 谈谈Android开发之RecyclerView的使用全解

    谈谈Android开发之RecyclerView的使用全解

    这篇文章主要介绍了谈谈Android开发之RecyclerView的使用全解,非常具有实用价值,需要的朋友可以参考下。
    2016-12-12
  • Android第三方微信支付教程

    Android第三方微信支付教程

    这篇文章主要为大家详细介绍了Android第三方微信支付教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Android 按后退键退出Android程序的实现方法

    Android 按后退键退出Android程序的实现方法

    本篇文章介绍了,在Android中按后退键退出Android程序的实现方法。需要的朋友参考下
    2013-04-04
  • Flutter 用自定义转场动画实现页面切换

    Flutter 用自定义转场动画实现页面切换

    本篇介绍了 fluro 导航到其他页面的自定义转场动画实现,Flutter本身提供了不少预定义的转场动画,可以通过 transitionBuilder 参数设计多种多样的转场动画,也可以通过自定义的 AnimatedWidget实现个性化的转场动画效果。
    2021-06-06
  • android使用ItemDecoration给RecyclerView 添加水印

    android使用ItemDecoration给RecyclerView 添加水印

    本篇文章主要介绍了android使用ItemDecoration给RecyclerView 添加水印,介绍了自定义Drawable来完成水印图片和使用ItemDecoration来布局水印,有兴趣的可以了解一下。
    2017-02-02
  • 详解Android系统中跨应用数据分享功能的实现

    详解Android系统中跨应用数据分享功能的实现

    这篇文章主要介绍了Android系统中跨应用数据分享功能的实现,文中分为发送文字、二进制内容和图片三种情况来讲,需要的朋友可以参考下
    2016-04-04
  • Android编程获取地理位置的经度和纬度实例

    Android编程获取地理位置的经度和纬度实例

    这篇文章主要介绍了Android编程获取地理位置的经度和纬度实现方法,结合实例形式详细分析了Android操作系统服务调用GPS实现定位的相关技巧,需要的朋友可以参考下
    2016-01-01
  • Android制作微信添加多个图片放大图片功能

    Android制作微信添加多个图片放大图片功能

    这篇文章主要介绍了Android制作微信添加多个图片放大图片功能,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-03-03

最新评论