Flutter學習之矢量圖SVG的區(qū)域填色示例詳解
請先看效果

具體步驟: 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.動畫:如此看來現(xiàn)在點擊填充的時候是不是有個動畫就更好了?
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,
),
);
},
)
再次看效果

這樣就可以實現(xiàn)一個填色小應用啦~代碼粗糙有待優(yōu)化 提供的是思路 自行修改 好了 能力有限就寫這么多啦~更多關于Flutter矢量圖SVG區(qū)域填色的資料請關注腳本之家其它相關文章!
相關文章
Android開發(fā)中PopupWindow用法實例分析
這篇文章主要介紹了Android開發(fā)中PopupWindow用法,結合實例形式分析了PopupWindow彈出窗口效果的使用技巧,需要的朋友可以參考下2016-02-02
Android中極簡的js與java的交互庫(SimpleJavaJsBridge)
本文主要介紹了Android中極簡的js與java的交互庫--SimpleJavaJsBridge,它可以讓js與java之間的通信更簡單。 具有很好的參考價值,下面跟著小編一起來看下吧2017-01-01
Flutter?Widget?之package?mason實現(xiàn)詳解
這篇文章主要為大家介紹了Flutter?Widget?之package:?mason實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
Android自定義View實現(xiàn)內(nèi)存清理加速球效果
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)內(nèi)存清理加速球的效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02
Android studio配置國內(nèi)鏡像源的實現(xiàn)
這篇文章主要介紹了Android studio配置國內(nèi)鏡像源的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
Android 網(wǎng)絡請求框架Volley實例詳解
這篇文章主要介紹了Android 網(wǎng)絡請求框架Volley實例詳解的相關資料,需要的朋友可以參考下2017-06-06

