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

這樣就可以實現一個填色小應用啦~代碼粗糙有待優(yōu)化 提供的是思路 自行修改 好了 能力有限就寫這么多啦~更多關于Flutter矢量圖SVG區(qū)域填色的資料請關注腳本之家其它相關文章!
相關文章
Flutter onTap中讓你脫穎而出的5條規(guī)則
這篇文章主要為大家介紹了Flutter onTap中讓你脫穎而出的5條規(guī)則,小事情決定了你的熟練程度,這些小細節(jié)的有趣之處在于它們的豐富性2023-11-11
談談Android開發(fā)之RecyclerView的使用全解
這篇文章主要介紹了談談Android開發(fā)之RecyclerView的使用全解,非常具有實用價值,需要的朋友可以參考下。2016-12-12
android使用ItemDecoration給RecyclerView 添加水印
本篇文章主要介紹了android使用ItemDecoration給RecyclerView 添加水印,介紹了自定義Drawable來完成水印圖片和使用ItemDecoration來布局水印,有興趣的可以了解一下。2017-02-02
詳解Android系統(tǒng)中跨應用數據分享功能的實現
這篇文章主要介紹了Android系統(tǒng)中跨應用數據分享功能的實現,文中分為發(fā)送文字、二進制內容和圖片三種情況來講,需要的朋友可以參考下2016-04-04

