How can I clip objects drawn outside a canvas? In the following, the black square represents the boundary of the canvas. I do not want the left half the circle to be drawn because it is outside the canvas:
This is simple example, but I am drawing PNGs and SVGs inside a canvas with various transformations applied to them, and I need a solution that would clip the portion drawn outside the canvas.
Here is the code for the above:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Container(
width: 200,
height: 200,
child: CustomPaint(
child: Container(),
painter: CanvasPainter(),
),
)),
),
);
}
}
class CanvasPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
canvas.drawRect(
Rect.fromLTWH(0, 0, size.width, size.height),
Paint()
..style = PaintingStyle.stroke
..color = Colors.black);
canvas.save();
canvas.translate(0.0, 100.0);
canvas.drawCircle(Offset(0, 0), 50.0, Paint()..color = Colors.blue);
canvas.restore();
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
CodePudding user response:
you need to add
canvas.clipRect(rect);
so your code be like that:
void paint(Canvas canvas, Size size) {
final rect = Rect.fromLTWH(0, 0, size.width, size.height);
canvas.drawRect(
rect,
Paint()
..style = PaintingStyle.stroke
..color = Colors.black);
canvas.clipRect(rect);
canvas.save();
canvas.translate(0.0, 100.0);
canvas.drawCircle(Offset(0, 0), 50.0, Paint()..color = Colors.blue);
canvas.restore();
}
CodePudding user response:
To prevent a widget to draw beyond its layout size, use ClipRect to clip it. For rounded rect shape use ClipRRect and ClipPath for custom shape.
ClipRect(
child: Container(
width: 200,
height: 200,
child: CustomPaint(
child: Container(),
painter: CanvasPainter(),
),
),
)
You can also use it before CustomPaint
.
I asked a similar question and this answer also solve for this case, and I'm just repeating it here.