fix alignment for dot grid background + add clipping post canvas paint

This commit is contained in:
2025-07-26 19:12:24 +00:00
parent 7ad54a92cb
commit 5a986eceb9
9 changed files with 94 additions and 39 deletions
+27 -9
View File
@@ -9,25 +9,28 @@ abstract class CanvasBackground {
/// draw the backround on this context. Implement this to have
/// different kinds of backgrounds
void paint(Canvas canvas, Offset offset, double scale, Size canvasSize);
/// [screenOffset] is the screen space offset for clipping
/// [canvasOffset] is the grid space offset from the controller
void paint(Canvas canvas, Offset screenOffset, Offset canvasOffset, double scale, Size canvasSize);
}
class NoBackground extends CanvasBackground {
const NoBackground();
@override
void paint(Canvas canvas, Offset offset, double scale, Size canvasSize) {}
void paint(Canvas canvas, Offset screenOffset, Offset canvasOffset, double scale, Size canvasSize) {}
}
class SingleColorBackround extends CanvasBackground {
const SingleColorBackround(Color backgroundColor) : super(bgColor: backgroundColor);
@override
void paint(Canvas canvas, Offset offset, double scale, Size canvasSize) {
void paint(Canvas canvas, Offset screenOffset, Offset canvasOffset, double scale, Size canvasSize) {
final paint = Paint()
..color = bgColor
..style = PaintingStyle.fill;
canvas.drawRect(Rect.fromLTWH(0, 0, canvasSize.width, canvasSize.height), paint);
canvas.drawRect(Rect.fromLTWH(screenOffset.dx, screenOffset.dy, canvasSize.width, canvasSize.height), paint);
}
}
@@ -39,18 +42,33 @@ class DotGridBackround extends CanvasBackground {
const DotGridBackround({this.size = 2.0, this.spacing = 50.0, this.color = Colors.black12}) : super();
@override
void paint(Canvas canvas, Offset offset, double scale, Size canvasSize) {
void paint(Canvas canvas, Offset screenOffset, Offset canvasOffset, double scale, Size canvasSize) {
final paint = Paint()
..color = color
..strokeWidth = 1.0 * scale;
double scaledSpacing = spacing * scale;
double scaledSize = size * scale;
double startX = (offset.dx % scaledSpacing) - scaledSpacing;
double startY = (offset.dy % scaledSpacing) - scaledSpacing;
// Use canvasOffset to determine the grid position in grid space
// Calculate the grid origin in canvas space (0,0 should be at a grid point)
// Find the first grid point that aligns with the coordinate system
double firstGridX = (canvasOffset.dx / spacing).floor() * spacing;
double firstGridY = (canvasOffset.dy / spacing).floor() * spacing;
for (double x = startX; x < canvasSize.width + scaledSpacing; x += scaledSpacing) {
for (double y = startY; y < canvasSize.height + scaledSpacing; y += scaledSpacing) {
// Convert grid space coordinates to screen space
double screenStartX = (firstGridX - canvasOffset.dx) * scale + screenOffset.dx;
double screenStartY = (firstGridY - canvasOffset.dy) * scale + screenOffset.dy;
// Ensure we start drawing before the visible area to avoid gaps
while (screenStartX > screenOffset.dx) {
screenStartX -= scaledSpacing;
}
while (screenStartY > screenOffset.dy) {
screenStartY -= scaledSpacing;
}
for (double x = screenStartX; x < screenOffset.dx + canvasSize.width + scaledSpacing; x += scaledSpacing) {
for (double y = screenStartY; y < screenOffset.dy + canvasSize.height + scaledSpacing; y += scaledSpacing) {
canvas.drawCircle(Offset(x, y), scaledSize, paint);
}
}