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

Flutter Canvas绘制线条避免叠加变粗问题求助

Flutter Canvas 避免线条重叠处变粗的解决方案

当在Flutter Canvas中绘制存在重叠区域的多条线条时,重叠部分会因多次绘制的像素叠加而视觉上变粗。比如以下代码就会出现该问题:

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawLine(const Offset(100, 100), const Offset(200, 200), Paint());
    canvas.drawLine(const Offset(100, 100), const Offset(400, 400), Paint());
  }

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

解决方案1:设置Paint的混合模式

通过给Paint设置blendMode: BlendMode.src,让新绘制的内容直接覆盖已有内容,而非叠加像素,从而避免重叠处变粗:

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..blendMode = BlendMode.src;
    canvas.drawLine(const Offset(100, 100), const Offset(200, 200), paint);
    canvas.drawLine(const Offset(100, 100), const Offset(400, 400), paint);
  }

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

解决方案2:合并路径,避免重复绘制

如果其中一条线是另一条线的子集(比如示例中第一条线完全包含在第二条线内),可以直接绘制最长的那条线,彻底避免重复绘制:

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // 直接绘制完整的长线,无需绘制短线
    canvas.drawLine(const Offset(100, 100), const Offset(400, 400), Paint());
  }

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

如果是两条部分重叠的交叉线条,可以使用Path.combine合并路径,只保留不重叠区域:

class MyPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final path1 = Path()
      ..moveTo(100, 100)
      ..lineTo(300, 300);
    final path2 = Path()
      ..moveTo(200, 100)
      ..lineTo(400, 300);
    
    // 合并路径,去除重叠部分后分别绘制
    final combinedPath = Path.combine(PathOperation.difference, path1, path2);
    canvas.drawPath(combinedPath, Paint());
    canvas.drawPath(path2, Paint());
  }

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

解决方案3:优化绘制精度

确保Paint开启抗锯齿(默认开启),同时尽量让线条坐标精确对齐像素边界,减少半透明像素叠加的概率:

final paint = Paint()..isAntiAlias = true;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:50:19