feat: voucher card

This commit is contained in:
efrilm
2025-08-27 19:37:22 +07:00
parent 8312429be3
commit 8412220a06
7 changed files with 501 additions and 2 deletions
@@ -0,0 +1,61 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class VoucherClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
double notchRadius = 10.0;
double notchPosition = size.height * 0.6; // Position of notch
// Start from top-left
path.moveTo(0, 12);
// Top edge with rounded corners
path.quadraticBezierTo(0, 0, 12, 0);
path.lineTo(size.width - 12, 0);
path.quadraticBezierTo(size.width, 0, size.width, 12);
// Right edge until notch
path.lineTo(size.width, notchPosition - notchRadius);
// Right notch (semicircle going inward)
path.arcToPoint(
Offset(size.width, notchPosition + notchRadius),
radius: Radius.circular(notchRadius),
clockwise: false,
);
// Continue right edge
path.lineTo(size.width, size.height - 12);
// Bottom edge
path.quadraticBezierTo(
size.width,
size.height,
size.width - 12,
size.height,
);
path.lineTo(12, size.height);
path.quadraticBezierTo(0, size.height, 0, size.height - 12);
// Left edge until notch
path.lineTo(0, notchPosition + notchRadius);
// Left notch (semicircle going inward)
path.arcToPoint(
Offset(0, notchPosition - notchRadius),
radius: Radius.circular(notchRadius),
clockwise: false,
);
// Close path
path.close();
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
class DashedLinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint()
..color = Colors.grey[300]!
..strokeWidth = 1
..style = PaintingStyle.stroke;
double dashWidth = 5;
double dashSpace = 3;
double startX = 0;
while (startX < size.width) {
canvas.drawLine(
Offset(startX, size.height / 2),
Offset(startX + dashWidth, size.height / 2),
paint,
);
startX += dashWidth + dashSpace;
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}