paint method
void
paint()
override
draw the backround on this context. Implement this to have
different kinds of backgrounds
screenOffset
is the screen space offset for clipping
canvasOffset
is the grid space offset from the controller
Implementation
@override
void paint(
Canvas canvas,
Offset screenOffset,
Offset canvasOffset,
double scale,
Size canvasSize,
) {
// Fill background
final rect = Rect.fromLTWH(
screenOffset.dx,
screenOffset.dy,
canvasSize.width,
canvasSize.height,
);
final bgPaint = Paint()
..color = backgroundColor
..style = PaintingStyle.fill;
canvas.drawRect(rect, bgPaint);
// Early out if dots are too dense or too small
final spacingSS = (spacing * scale).abs();
final radiusSS = (size * scale).abs();
if (spacingSS < 1.0 || radiusSS < 0.25) {
return; // background already drawn
}
final dotPaint = Paint()
..color = dotColor
..style = PaintingStyle.fill;
// Choose pan semantics
final sign = naturalPan ? 1.0 : -1.0;
// Determine visible grid-space bounds to iterate
// Screen rect spans [screenOffset, screenOffset + canvasSize]
// xSS = screenOffset.x + (xGS - sign*canvasOffset.x) * scale
// Solve for xGS bounds to cover the screen rect (+radius margin)
final marginGSX = radiusSS / scale;
final marginGSY = radiusSS / scale;
final xGsMin = sign * canvasOffset.dx - marginGSX;
final xGsMax =
sign * canvasOffset.dx + (canvasSize.width + 2 * radiusSS) / scale;
final yGsMin = sign * canvasOffset.dy - marginGSY;
final yGsMax =
sign * canvasOffset.dy + (canvasSize.height + 2 * radiusSS) / scale;
int nStartX = (xGsMin / spacing).floor();
int nEndX = (xGsMax / spacing).ceil();
int nStartY = (yGsMin / spacing).floor();
int nEndY = (yGsMax / spacing).ceil();
// Iterate grid and draw circles
for (int nx = nStartX; nx <= nEndX; nx++) {
final xGS = nx * spacing;
final xSS = screenOffset.dx + (xGS - sign * canvasOffset.dx) * scale;
if (xSS + radiusSS < rect.left || xSS - radiusSS > rect.right)
continue; // skip out-of-bounds columns
for (int ny = nStartY; ny <= nEndY; ny++) {
final yGS = ny * spacing;
final ySS = screenOffset.dy + (yGS - sign * canvasOffset.dy) * scale;
if (ySS + radiusSS < rect.top || ySS - radiusSS > rect.bottom)
continue; // skip out-of-bounds rows
canvas.drawCircle(Offset(xSS, ySS), radiusSS, dotPaint);
}
}
}