Is it possible to achieve or stack paint object over another like this. I tried many resources for custom painter but was not able to stack the text in center of the circle and applying gradient behind circle. Help appreciated.
CodePudding user response:
You don't need Custom paint to achieve this. You can create the layout using stack like the following
Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.orangeAccent.withOpacity(0.4),
Colors.transparent
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
stops: [0.4, 1])),
width: 100,
height: 200,
),
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.deepPurple,
border: Border.all(color: Colors.white, width: 3)),
width: 100,
height: 100,
child: Center(
child: Text(
"80",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w900,
color: Colors.white),
)),
),
],
)
CodePudding user response:
You can use Kaushik's answer, it's simpler and straight forward. However, if you have to use CustomPaint, here's how I would do it:
@override
void paint(Canvas canvas, Size size) {
// top left point of shader rectangle
var pointA = Offset(size.width * 0.2, 0);
// define rectangle
var rect = pointA & Size(size.width * 0.6, size.height);
// Define a paint with shader
final Paint shaderPaint = Paint()
..color = Colors.yellow
..style = PaintingStyle.fill
..strokeWidth = 1
..shader = const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.deepPurple,
Colors.yellow,
]).createShader(rect);
// draw rectangle
canvas.drawRect(rect, shaderPaint);
// paint for circle
final Paint circlePaintFill = Paint()
..color = Colors.deepPurple
..style = PaintingStyle.fill;
final Paint circlePaintStroke = Paint()
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 5;
// draw circle
canvas.drawCircle(Offset(size.width * 0.5, size.height * 0.3),
size.width * 0.3, circlePaintFill);
canvas.drawCircle(Offset(size.width * 0.5, size.height * 0.3),
size.width * 0.3, circlePaintStroke);
//draw text
const textStyle = TextStyle(
color: Colors.white, fontSize: 60, fontWeight: FontWeight.bold);
const textSpan = TextSpan(
text: '80',
style: textStyle,
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
);
textPainter.layout(
minWidth: 0,
maxWidth: size.width,
);
// position of text
final xCenter = (size.width - textPainter.width) / 2;
final yCenter = (size.height * 0.6 - textPainter.height) / 2;
final offset = Offset(xCenter, yCenter);
textPainter.paint(canvas, offset);
}
You'll have to adjust the size value inside custom painter based on the size you define outside the custom painter