Flutter學(xué)習(xí)之矢量圖SVG的區(qū)域填色示例詳解
請(qǐng)先看效果
具體步驟: 1.SVG實(shí)際上就是一個(gè)xml文件,通過flutter自帶的package xml進(jìn)行進(jìn)行圖層解析 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(() {}); // 在這里處理點(diǎn)擊事件 }, 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.動(dòng)畫:如此看來現(xiàn)在點(diǎn)擊填充的時(shí)候是不是有個(gè)動(dòng)畫就更好了?
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, ), ); }, )
再次看效果
這樣就可以實(shí)現(xiàn)一個(gè)填色小應(yīng)用啦~代碼粗糙有待優(yōu)化 提供的是思路 自行修改 好了 能力有限就寫這么多啦~更多關(guān)于Flutter矢量圖SVG區(qū)域填色的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開發(fā)中PopupWindow用法實(shí)例分析
這篇文章主要介紹了Android開發(fā)中PopupWindow用法,結(jié)合實(shí)例形式分析了PopupWindow彈出窗口效果的使用技巧,需要的朋友可以參考下2016-02-02Android中極簡的js與java的交互庫(SimpleJavaJsBridge)
本文主要介紹了Android中極簡的js與java的交互庫--SimpleJavaJsBridge,它可以讓js與java之間的通信更簡單。 具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01Flutter?Widget?之package?mason實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Flutter?Widget?之package:?mason實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android自定義View實(shí)現(xiàn)內(nèi)存清理加速球效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)內(nèi)存清理加速球的效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android studio配置國內(nèi)鏡像源的實(shí)現(xiàn)
這篇文章主要介紹了Android studio配置國內(nèi)鏡像源的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Android 網(wǎng)絡(luò)請(qǐng)求框架Volley實(shí)例詳解
這篇文章主要介紹了Android 網(wǎng)絡(luò)請(qǐng)求框架Volley實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06Android 項(xiàng)目實(shí)戰(zhàn)之頭像選擇功能
這篇文章主要介紹了Android 項(xiàng)目實(shí)戰(zhàn)頭像選擇功能實(shí)戰(zhàn),需要的朋友可以參考下2018-01-01Android實(shí)現(xiàn)隨手指移動(dòng)小球
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)隨手指移動(dòng)小球,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08