I want to have border/corner radius for my diamond widget.
Something like this:
BorderRadius.all(Radius.circular(cornerRadius))
I should probably use arcToPoint, arcTo or quadraticBezierTo functions of the Path, but can't find any good documentation/examples.
import 'package:flutter/material.dart';
/// Diamond Widget
class Diamond extends StatelessWidget {
/// Constructor
const Diamond({
required this.width,
required this.height,
this.lineColor = Colors.black,
this.cornerRadius = 8.0,
super.key,
});
/// Width of the diamond
final double width;
/// Height of the diamond
final double height;
/// Outline's color of the diamond
final Color lineColor;
/// Corner radius of the diamond
final double cornerRadius;
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(width, height),
painter: _DiamondPainter(
lineColor: lineColor,
cornerRadius: cornerRadius,
),
);
}
}
/// Custom painter for drawing a diamond
class _DiamondPainter extends CustomPainter {
_DiamondPainter({required this.lineColor, required this.cornerRadius});
final Color lineColor;
final double cornerRadius;
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..style = PaintingStyle.stroke
..color = lineColor
..strokeWidth = 2.0;
final Path path = Path()
..moveTo(size.width / 2, 0) // Top center
..lineTo(size.width, size.height / 2) // Right center
..lineTo(size.width / 2, size.height) // Bottom center
..lineTo(0, size.height / 2) // Left center
..close();
canvas.drawPath(path, paint); // Draw the outlined diamond
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
This is the incomplete example code that draws a diamond correctly, but without rounded corners. I want to complete this code and use cornerRadius
in the implementation.
I tried using RRect and clips, but they didn't work either.
I found your thought about using Bezier curves interesting and decided to give it a try. I'm not sure if this is the most efficient implementation, but it works as you described. If I got it right, of course! :)
I slightly modified paint
from your painter. Here it is :
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..style = PaintingStyle.stroke
..color = lineColor
..strokeWidth = 2.0;
final Path path = Path()
..moveTo(size.width / 2 + cornerRadius, 0 + cornerRadius) // Top center
..lineTo(size.width - cornerRadius,
size.height / 2 - cornerRadius) // Right center
..quadraticBezierTo(size.width, size.height / 2,
size.width - cornerRadius, size.height / 2 + cornerRadius)
..lineTo(size.width / 2 + cornerRadius,
size.height - cornerRadius) // Bottom center
..quadraticBezierTo(size.width / 2, size.height,
size.width / 2 - cornerRadius, size.height - cornerRadius)
..lineTo(0 + cornerRadius, size.height / 2 + cornerRadius) // Left center
..quadraticBezierTo(
0, size.height / 2, 0 + cornerRadius, size.height / 2 - cornerRadius)
..lineTo(size.width / 2 - cornerRadius, 0 + cornerRadius)
..quadraticBezierTo(
size.width / 2, 0, size.width / 2 + cornerRadius, 0 + cornerRadius);
canvas.drawPath(path, paint); // Draw the outlined diamond
}
The key concept here is to provide offsets for each line, which would create "empty corners." Then, we fill these gaps with Bezier curves to achieve the rounded corners.
plus, I believe you should somehow validate cornerRadius
parameter, since it can't be greater than half of diamond's side size. And also, my implementation will only work for square diamond :( But I still think it's good starting point for your issue