Flutter Canvas绘制网格异常:部分线条半透明或未显示
Flutter Canvas绘制网格线条半透明/不显示问题解决
你遇到的线条半透明、部分不渲染问题,核心是浮点坐标的像素对齐问题和循环边界精度误差:当线条的x/y坐标落在像素边界之间时,Flutter Canvas会触发抗锯齿处理,导致线条呈现半透明;而浮点数累加的精度偏差,可能让循环提前结束,遗漏最后一条线条。
以下是具体修复方案:
1. 强制坐标像素对齐
将线条坐标修正为整数像素值,避免抗锯齿导致的半透明效果,直接使用roundToDouble()对坐标取整:
void _drawVerticalLines(Canvas c) { for (double x = start.dx; x <= end.dx; x += cellSize) { final alignedX = x.roundToDouble(); c.drawLine(Offset(alignedX, start.dy), Offset(alignedX, end.dy), Styles.red); } } void _drawHorizontalLines(Canvas c) { for (double y = start.dy; y <= end.dy; y += cellSize) { final alignedY = y.roundToDouble(); c.drawLine(Offset(start.dx, alignedY), Offset(end.dx, alignedY), Styles.blue); } }
2. 修正循环边界精度问题
浮点数多次累加后可能出现精度偏差,比如x实际略大于end.dx但因精度显示为相等,导致最后一条线被跳过。给边界值增加微小偏移量,确保循环能覆盖最后一条线条:
void _drawVerticalLines(Canvas c) { final maxX = end.dx + 0.5; for (double x = start.dx; x <= maxX; x += cellSize) { final alignedX = x.roundToDouble(); c.drawLine(Offset(alignedX, start.dy), Offset(alignedX, end.dy), Styles.red); } } void _drawHorizontalLines(Canvas c) { final maxY = end.dy + 0.5; for (double y = start.dy; y <= maxY; y += cellSize) { final alignedY = y.roundToDouble(); c.drawLine(Offset(start.dx, alignedY), Offset(end.dx, alignedY), Styles.blue); } }
可选:禁用抗锯齿(不推荐)
如果不需要抗锯齿效果,可临时禁用,但会导致线条边缘生硬,不如像素对齐方案优雅:
void _drawVerticalLines(Canvas c) { c.save(); c.setFilterQuality(FilterQuality.none); for (double x = start.dx; x <= end.dx + 0.5; x += cellSize) { c.drawLine(Offset(x, start.dy), Offset(x, end.dy), Styles.red); } c.restore(); }
修改后重新运行,线条即可完全不透明且全部渲染。
内容的提问来源于stack exchange,提问作者Jan Cahlík
相关产品推荐
相关产品推荐

