Skip to content

Instantly share code, notes, and snippets.

@matifdeveloper
Created July 4, 2024 05:27
Show Gist options
  • Save matifdeveloper/d34405787b7c8d272abb5b472fda94cb to your computer and use it in GitHub Desktop.
Save matifdeveloper/d34405787b7c8d272abb5b472fda94cb to your computer and use it in GitHub Desktop.
Custom dotted border in flutter
import 'package:flutter/material.dart';
class DottedBorder extends StatelessWidget {
final double strokeWidth;
final Color color;
final double dashLength;
final double dashGap;
final Shape shape;
final Widget child;
const DottedBorder({
super.key,
this.strokeWidth = 2.0,
this.color = Colors.black,
this.dashLength = 4.0,
this.dashGap = 2.0,
this.shape = Shape.rectangle,
required this.child,
});
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: DottedBorderPainter(
shape: shape,
strokeWidth: strokeWidth,
color: color,
dashGap: dashGap,
dashLength: dashLength,
),
child: child,
);
}
}
enum Shape { rectangle, circle }
class DottedBorderPainter extends CustomPainter {
final double strokeWidth;
final Color color;
final double dashLength;
final double dashGap;
final Shape shape;
DottedBorderPainter({
this.strokeWidth = 2.0,
this.color = Colors.black,
this.dashLength = 4.0,
this.dashGap = 2.0,
this.shape = Shape.rectangle,
});
@override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()
..color = color
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
if (shape == Shape.rectangle) {
drawDottedLine(
canvas, const Offset(0, 0), Offset(size.width, 0), paint); // Top
drawDottedLine(canvas, Offset(size.width, 0),
Offset(size.width, size.height), paint); // Right
drawDottedLine(canvas, Offset(size.width, size.height),
Offset(0, size.height), paint); // Bottom
drawDottedLine(
canvas, Offset(0, size.height), const Offset(0, 0), paint); // Left
} else if (shape == Shape.circle) {
drawDottedCircle(canvas, Offset(size.width / 2, size.height / 2),
size.width / 2, paint);
}
}
void drawDottedLine(Canvas canvas, Offset start, Offset end, Paint paint) {
double totalLength = (start - end).distance;
double dashLengthWithGap = dashLength + dashGap;
double dashCount = (totalLength / dashLengthWithGap).floorToDouble();
double dashLengthActual = totalLength / dashCount - dashGap;
for (int i = 0; i < dashCount; i++) {
double currentLength = i * dashLengthWithGap;
Offset from = Offset.lerp(start, end, currentLength / totalLength)!;
Offset to = Offset.lerp(
start, end, (currentLength + dashLengthActual) / totalLength)!;
canvas.drawLine(from, to, paint);
}
}
void drawDottedCircle(
Canvas canvas, Offset center, double radius, Paint paint) {
double circumference = 2 * 3.14159265358979323846 * radius;
double dashCount = (circumference / (dashLength + dashGap)).floorToDouble();
double dashArcLength = 2 * 3.14159265358979323846 / dashCount;
for (int i = 0; i < dashCount; i++) {
double startAngle = i * dashArcLength;
double endAngle = startAngle + (dashLength / radius);
canvas.drawArc(Rect.fromCircle(center: center, radius: radius),
startAngle, endAngle - startAngle, false, paint);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment