728x90
1. 티켓 모양
class TicketWidget extends StatelessWidget {
const TicketWidget({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16),
child: SizedBox(
height: 188,
width: double.infinity,
child: CustomPaint(
painter: TicketPainter(),
),
),
),
),
);
}
}
class TicketPainter extends CustomPainter {
final _paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1
..color = Colors.grey;
final _linePaint = Paint()
..strokeWidth = 1
..color = Colors.grey.shade300
..style = PaintingStyle.stroke;
static const double _ticketRadius = 4;
static const double _lineWidth = 0.825;
static const double _holeRadius = 8;
static const dotHeight = 8;
static const dotPadding = 4;
@override
void paint(Canvas canvas, Size size) {
final height = size.height;
final width = size.width;
final lineWidth = width * _lineWidth;
Path path = Path()
..moveTo(0, _ticketRadius)
..lineTo(0, height - _ticketRadius)
..quadraticBezierTo(0, height, _ticketRadius, height)
..arcTo(
Rect.fromCircle(center: Offset(lineWidth, height), radius: _holeRadius),
pi,
pi,
false,
)
..lineTo(width - _ticketRadius, height)
..quadraticBezierTo(width, height, width, height - _ticketRadius)
..lineTo(width, _ticketRadius)
..quadraticBezierTo(width, 0, width - _ticketRadius, 0)
..arcTo(
Rect.fromCircle(center: Offset(lineWidth, 0), radius: _holeRadius),
0,
pi,
false,
)
..lineTo(_ticketRadius, 0)
..quadraticBezierTo(0, 0, 0, _ticketRadius);
canvas.drawPath(path, _paint);
path = Path()
..moveTo(lineWidth, _holeRadius + 12)
..lineTo(lineWidth, _holeRadius + 12 + 4);
double blank = _holeRadius + 12 + 4;
final dotCount = ((height - ((blank) * 2)) / (dotPadding + dotHeight)).floor();
for(var i = 0; i < dotCount; i++) {
path.moveTo(lineWidth, blank + dotPadding);
path.lineTo(lineWidth, blank + dotPadding + dotHeight);
blank += dotPadding + dotHeight;
}
path.moveTo(lineWidth, blank + dotPadding);
path.lineTo(lineWidth, blank + dotPadding + 4);
canvas.drawPath(path, _linePaint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
2. 티켓 모양 v2
class TicketWidget extends StatelessWidget {
const TicketWidget({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16),
child: SizedBox(
height: 186,
width: double.infinity,
child: CustomPaint(
painter: TicketPainter(),
),
),
),
),
);
}
}
class TicketPainter extends CustomPainter {
final _paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1
..color = Colors.grey;
final _linePaint = Paint()
..strokeWidth = 1
..color = Colors.grey.shade300
..style = PaintingStyle.stroke;
static const double _ticketRadius = 4;
static const double _lineHeight = 0.2473;
static const double _holeRadius = 8;
static const dotWidth = 8;
static const dotPadding = 4;
@override
void paint(Canvas canvas, Size size) {
final height = size.height;
final width = size.width;
final lineHeight = height * _lineHeight;
Path path = Path()
..moveTo(0, _ticketRadius)
..arcTo(
Rect.fromCircle(center: Offset(0, lineHeight), radius: _holeRadius),
-pi / 2,
pi,
false,
)
..lineTo(0, height - _ticketRadius)
..quadraticBezierTo(0, height, _ticketRadius, height)
..lineTo(width - _ticketRadius, height)
..quadraticBezierTo(width, height, width, height - _ticketRadius)
..arcTo(
Rect.fromCircle(center: Offset(width, lineHeight), radius: _holeRadius),
pi / 2,
pi,
false,
)
..lineTo(width, _ticketRadius)
..quadraticBezierTo(width, 0, width - _ticketRadius, 0)
..lineTo(_ticketRadius, 0)
..quadraticBezierTo(0, 0, 0, _ticketRadius);
canvas.drawPath(path, _paint);
path = Path()
..moveTo(_holeRadius + 14, lineHeight)
..lineTo(_holeRadius + 14 + 4, lineHeight);
double blank = _holeRadius + 14 + 4;
final dotCount =
((width - ((blank) * 2)) / (dotPadding + dotWidth)).floor();
for (var i = 0; i < dotCount; i++) {
path.moveTo(blank + dotPadding, lineHeight);
path.lineTo(blank + dotPadding + dotWidth, lineHeight);
blank += dotPadding + dotWidth;
}
path.moveTo(blank + dotPadding, lineHeight);
path.lineTo(blank + dotPadding + 4, lineHeight);
canvas.drawPath(path, _linePaint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
'Flutter > 기본' 카테고리의 다른 글
[Flutter] TextScale fix (텍스트 크기 고정) (0) | 2024.01.08 |
---|---|
[Flutter] Clipboard 사용해서 복사 / 가져오기 (2) | 2024.01.04 |
[Flutter] Custom Icon generator (SVG to Icon) (2) | 2023.11.23 |
[Flutter] web device local debug test (0) | 2023.11.01 |
[Flutter] TextField 복사/붙여넣기 비활성화 (0) | 2023.08.09 |