You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从SVG提取路径后使用path_drawing包绘制无效果问题

SVG路径在Flutter CustomPainter中无法显示的解决方法

问题场景

从世界地图SVG中提取的单个国家路径(比如安道尔),用parseSvgPathData转成Path对象后,结合touchable库的CustomPainter完全看不到绘制内容,但用示例里的路径数据就能正常显示。

问题原因

  1. 坐标不匹配:SVG原始路径的坐标数值很大,远远超出Flutter默认画布的可视范围,导致路径绘制在画布外看不到。
  2. 绘制样式问题:只设置了描边宽度,但没开启填充,细小的描边可能因为坐标问题更难被看到。

解决方案

1. 适配路径坐标

对提取的SVG路径做缩放和平移,把它挪到Flutter画布的可视区域内。比如先缩小路径尺寸,再平移到画布中心。

2. 调整绘制样式

给Paint添加填充样式,封闭路径填充后更容易观察到效果。

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:path_drawing/path_drawing.dart';
import 'package:touchable/touchable.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CanvasTouchDetector(
        gesturesToOverride: const [GestureType.onTapUp],
        builder: (context) {
          return CustomPaint(
            size: const Size(double.infinity, double.infinity),
            painter: MyPainter(context),
          );
        },
      ),
    );
  }
}

class MyPainter extends CustomPainter {
  final BuildContext context;
  MyPainter(this.context);

  @override
  void paint(Canvas canvas, Size size) {
    TouchyCanvas touchyCanvas = TouchyCanvas(context, canvas);

    // 安道尔的SVG路径数据
    final String pathData = '''m 479.68275,331.6274 -0.077,0.025 -0.258,0.155 -0.147,0.054 -0.134,0.027 -0.105,-0.011 -0.058,-0.091 0.006,-0.139 -0.024,-0.124 -0.02,-0.067 0.038,-0.181 0.086,-0.097 0.119,-0.08 0.188,0.029 0.398,0.116 0.083,0.109 10e-4,0.072 -0.073,0.119 z''';

    Path path = parseSvgPathData(pathData);

    // 缩放和平移路径,适配当前画布尺寸
    // 缩放比例可根据实际SVG尺寸调整
    final scale = 0.2;
    // 计算平移量,把路径中心移到画布中心
    final translateX = size.width / 2 - 479.68275 * scale;
    final translateY = size.height / 2 - 331.6274 * scale;

    // 先平移画布,再缩放,确保路径显示在中心
    canvas.translate(translateX, translateY);
    canvas.scale(scale);

    touchyCanvas.drawPath(
      path,
      Paint()
        ..color = Colors.red
        ..strokeWidth = 2
        ..style = PaintingStyle.fill, // 开启填充,更容易看到效果
      onTapUp: (details) {
        print('安道尔区域被点击');
      },
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

关键修改说明

  • 去掉了不必要的路径拆分:单个路径不需要按换行分割,直接用完整字符串即可。
  • 添加画布变换:通过scale缩小路径,translate把路径移到画布中心,解决坐标超出可视范围的问题。
  • 开启填充样式:PaintingStyle.fill让封闭的国家路径显示填充色,更容易确认绘制成功。

内容的提问来源于stack exchange,提问作者dipansh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:55:16