I have a custom canvas that sits as stack on top of my other widgets.
The PainterPoint is as follows:
class PainterPoint {
bool isEnd;
Color color;
Offset offset;
double strokeSize;
BlendMode blendMode;
PainterPoint({
required this.offset,
required this.isEnd,
this.strokeSize = 2,
this.color = Colors.blue,
this.blendMode = BlendMode.color,
});
}
And finally the BrushPainter is as:
class BrushPainter extends CustomPainter {
final List<PainterPoint> points;
BrushPainter({required this.points});
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()..strokeCap = StrokeCap.round;
for (int i = 0; i < points.length - 1; i++) {
if (points[i].isEnd) {
continue;
}
final currentPoint = points[i];
final nextPoint = points[i + 1];
paint.color = currentPoint.color;
paint.strokeWidth = currentPoint.strokeSize;
paint.blendMode = currentPoint.blendMode;
if (nextPoint.isEnd) {
canvas.drawPoints(PointMode.points, [currentPoint.offset], paint);
} else {
canvas.drawLine(currentPoint.offset, nextPoint.offset, paint);
}
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
But when I try to draw something the experience get laggy way too quickly. Even after a few points(after about 80-90 points) drawn the entire thing lags.
As you can see inside the gesture detector, if the EditorMode is EDIT_MODE and the isEraserPainter is true I am trying to cleanup the previously drawn points with BlendMode. So a lot of points will be drawn.
I have seen articles and posts on stack overflow but none of them included any sample code or good explanation as of yet.
2
Answers
The final solution following @HannesH's answer is:
Maybe instead of using
canvas.drawLine
for every segment, create a new path (before the loop) and add each segment withpath.lineTo
. After the loop draw the whole path by usingcanvas.drawPath
.This will result in only one (complex but highly optimized) draw-call per frame instead of n.
This has the additional benefit that you can simply swap
lineTo
with something more complex likequadraticBezierTo
to smooth out the path.you would have to group your points into paths with corresponding blend mode though..
also my inner programmer cries a little when i see
? true : false
😉