creek

The AI Image Editor of 2030

lib/ui/painters/canvas_painter.dart (2508B)


 1import 'dart:ui' as ui;
 2import 'package:flutter/material.dart';
 3import 'package:creekui/data/models/canvas_models.dart';
 4
 5class CanvasPainter extends CustomPainter {
 6  final List<DrawingPath> paths;
 7  final List<DrawingPoint> currentPoints;
 8  final Color currentColor;
 9  final double currentWidth;
10  final bool isEraser;
11
12  // Visual highlight/flash
13  final Color? overrideColor;
14
15  CanvasPainter({
16    required this.paths,
17    required this.currentPoints,
18    required this.currentColor,
19    required this.currentWidth,
20    required this.isEraser,
21    this.overrideColor,
22  });
23
24  @override
25  void paint(Canvas canvas, Size size) {
26    canvas.saveLayer(Rect.fromLTWH(0, 0, size.width, size.height), Paint());
27
28    // Draw saved paths
29    for (final path in paths) {
30      _drawPath(canvas, path);
31    }
32
33    // Draw active stroke
34    if (currentPoints.isNotEmpty) {
35      final paint =
36          Paint()
37            ..color =
38                isEraser ? Colors.transparent : (overrideColor ?? currentColor)
39            ..blendMode = isEraser ? BlendMode.clear : BlendMode.srcOver
40            ..strokeWidth = currentWidth
41            ..strokeCap = StrokeCap.round
42            ..strokeJoin = StrokeJoin.round
43            ..style = PaintingStyle.stroke;
44
45      final Path p = Path();
46      p.moveTo(currentPoints.first.offset.dx, currentPoints.first.offset.dy);
47      for (int i = 1; i < currentPoints.length; i++) {
48        p.lineTo(currentPoints[i].offset.dx, currentPoints[i].offset.dy);
49      }
50      canvas.drawPath(p, paint);
51    }
52    canvas.restore();
53  }
54
55  void _drawPath(Canvas canvas, DrawingPath path) {
56    final paint =
57        Paint()
58          ..color =
59              path.isEraser ? Colors.transparent : (overrideColor ?? path.color)
60          ..blendMode = path.isEraser ? BlendMode.clear : BlendMode.srcOver
61          ..strokeWidth = path.strokeWidth
62          ..strokeCap = StrokeCap.round
63          ..strokeJoin = StrokeJoin.round
64          ..style = PaintingStyle.stroke;
65
66    if (path.points.length > 1) {
67      final Path p = Path();
68      p.moveTo(path.points.first.offset.dx, path.points.first.offset.dy);
69      for (int i = 1; i < path.points.length; i++) {
70        p.lineTo(path.points[i].offset.dx, path.points[i].offset.dy);
71      }
72      canvas.drawPath(p, paint);
73    } else if (path.points.isNotEmpty) {
74      canvas.drawPoints(ui.PointMode.points, [path.points.first.offset], paint);
75    }
76  }
77
78  @override
79  bool shouldRepaint(covariant CanvasPainter oldDelegate) => true;
80}