diff --git a/lib/ui/app/dashed_rect.dart b/lib/ui/app/dashed_rect.dart new file mode 100644 index 000000000..cf5f04365 --- /dev/null +++ b/lib/ui/app/dashed_rect.dart @@ -0,0 +1,115 @@ +// 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: 100, + 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 a, + @required math.Point 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, currentPoint.y) + : path.moveTo(currentPoint.x, currentPoint.y); + shouldDraw = !shouldDraw; + currentPoint = math.Point( + currentPoint.x + dx, + currentPoint.y + dy, + ); + } + return path; + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) { + return true; + } +}