116 lines
2.8 KiB
Dart
116 lines
2.8 KiB
Dart
// https://stackoverflow.com/a/55428017/497368
|
|
import 'package:flutter/material.dart';
|
|
import 'dart:math' as math;
|
|
|
|
class DashedRect extends StatelessWidget {
|
|
const DashedRect(
|
|
{this.color = Colors.black, this.strokeWidth = 1.0, this.gap = 5.0});
|
|
|
|
final Color color;
|
|
final double strokeWidth;
|
|
final double gap;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
height: 75,
|
|
width: double.infinity,
|
|
child: Padding(
|
|
padding: EdgeInsets.all(strokeWidth / 2),
|
|
child: CustomPaint(
|
|
painter:
|
|
DashRectPainter(color: color, strokeWidth: strokeWidth, gap: gap),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class DashRectPainter extends CustomPainter {
|
|
DashRectPainter(
|
|
{this.strokeWidth = 5.0, this.color = Colors.red, this.gap = 5.0});
|
|
|
|
double strokeWidth;
|
|
Color color;
|
|
double gap;
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final dashedPaint = Paint()
|
|
..color = color
|
|
..strokeWidth = strokeWidth
|
|
..style = PaintingStyle.stroke;
|
|
|
|
final x = size.width;
|
|
final y = size.height;
|
|
|
|
final _topPath = getDashedPath(
|
|
a: math.Point(0, 0),
|
|
b: math.Point(x, 0),
|
|
gap: gap,
|
|
);
|
|
|
|
final _rightPath = getDashedPath(
|
|
a: math.Point(x, 0),
|
|
b: math.Point(x, y),
|
|
gap: gap,
|
|
);
|
|
|
|
final _bottomPath = getDashedPath(
|
|
a: math.Point(0, y),
|
|
b: math.Point(x, y),
|
|
gap: gap,
|
|
);
|
|
|
|
final _leftPath = getDashedPath(
|
|
a: math.Point(0, 0),
|
|
b: math.Point(0.001, y),
|
|
gap: gap,
|
|
);
|
|
|
|
canvas.drawPath(_topPath, dashedPaint);
|
|
canvas.drawPath(_rightPath, dashedPaint);
|
|
canvas.drawPath(_bottomPath, dashedPaint);
|
|
canvas.drawPath(_leftPath, dashedPaint);
|
|
}
|
|
|
|
Path getDashedPath({
|
|
required math.Point<double> a,
|
|
required math.Point<double> b,
|
|
required double gap,
|
|
}) {
|
|
final size = Size(b.x - a.x, b.y - a.y);
|
|
final path = Path();
|
|
path.moveTo(a.x, a.y);
|
|
bool shouldDraw = true;
|
|
math.Point currentPoint = math.Point(a.x, a.y);
|
|
|
|
final radians = math.atan(size.height / size.width);
|
|
|
|
final dx = math.cos(radians) * gap < 0
|
|
? math.cos(radians) * gap * -1
|
|
: math.cos(radians) * gap;
|
|
|
|
final dy = math.sin(radians) * gap < 0
|
|
? math.sin(radians) * gap * -1
|
|
: math.sin(radians) * gap;
|
|
|
|
while (currentPoint.x <= b.x && currentPoint.y <= b.y) {
|
|
shouldDraw
|
|
? path.lineTo(currentPoint.x as double, currentPoint.y as double)
|
|
: path.moveTo(currentPoint.x as double, currentPoint.y as double);
|
|
shouldDraw = !shouldDraw;
|
|
currentPoint = math.Point(
|
|
currentPoint.x + dx,
|
|
currentPoint.y + dy,
|
|
);
|
|
}
|
|
return path;
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(CustomPainter oldDelegate) {
|
|
return true;
|
|
}
|
|
}
|