import 'dart:math' as math; import 'package:flutter/material.dart'; import '../../presentation/pages/mini_games/ferris_wheel/data/model.dart'; import '../theme/theme.dart'; class WheelPainter extends CustomPainter { final List sections; WheelPainter({required this.sections}); @override void paint(Canvas canvas, Size size) { final center = Offset(size.width / 2, size.height / 2); final radius = size.width / 2; final sectionAngle = 2 * math.pi / sections.length; // Draw outer white border final outerBorderPaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill; canvas.drawCircle(center, radius, outerBorderPaint); // Draw blue border ring final blueBorderPaint = Paint() ..color = const Color(0xFF3B82F6) ..style = PaintingStyle.fill; canvas.drawCircle(center, radius - 8, blueBorderPaint); // Draw inner white circle final innerWhitePaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill; canvas.drawCircle(center, radius - 20, innerWhitePaint); // Draw sections for (int i = 0; i < sections.length; i++) { final startAngle = i * sectionAngle - math.pi / 2; // Section background final sectionPaint = Paint() ..color = sections[i].color ..style = PaintingStyle.fill; canvas.drawArc( Rect.fromCircle(center: center, radius: radius - 22), startAngle, sectionAngle, true, sectionPaint, ); // Draw icon in each section final iconAngle = startAngle + sectionAngle / 2; final iconPosition = Offset( center.dx + (radius - 60) * math.cos(iconAngle), center.dy + (radius - 60) * math.sin(iconAngle), ); // Draw icon background circle final iconBgPaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill; canvas.drawCircle(iconPosition, 16, iconBgPaint); // Save canvas state for icon drawing canvas.save(); canvas.translate(iconPosition.dx, iconPosition.dy); // Draw icon using TextPainter to simulate Icon widget final iconText = _getIconText(sections[i].icon); final iconTextPainter = TextPainter( text: TextSpan( text: iconText, style: TextStyle( fontFamily: 'MaterialIcons', fontSize: 20, color: sections[i].color, fontWeight: FontWeight.normal, ), ), textDirection: TextDirection.ltr, ); iconTextPainter.layout(); iconTextPainter.paint( canvas, Offset(-iconTextPainter.width / 2, -iconTextPainter.height / 2), ); canvas.restore(); // Draw prize text final textAngle = startAngle + sectionAngle / 2; final textPosition = Offset( center.dx + (radius - 100) * math.cos(textAngle), center.dy + (radius - 100) * math.sin(textAngle), ); // Save canvas state for text rotation canvas.save(); canvas.translate(textPosition.dx, textPosition.dy); canvas.rotate(textAngle + math.pi / 2); final textPainter = TextPainter( text: TextSpan( text: sections[i].prize, style: const TextStyle( color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold, ), ), textDirection: TextDirection.ltr, ); textPainter.layout(); textPainter.paint( canvas, Offset(-textPainter.width / 2, -textPainter.height / 2), ); canvas.restore(); } // Draw white dots around the outer edge final dotPaint = Paint() ..color = Colors.white ..style = PaintingStyle.fill; for (int i = 0; i < 24; i++) { final dotAngle = (2 * math.pi / 24) * i; final dotPosition = Offset( center.dx + (radius - 14) * math.cos(dotAngle), center.dy + (radius - 14) * math.sin(dotAngle), ); canvas.drawCircle(dotPosition, 3, dotPaint); } // Draw section dividers final dividerPaint = Paint() ..color = AppColor.white ..style = PaintingStyle.stroke ..strokeWidth = 2; for (int i = 0; i < sections.length; i++) { final angle = i * sectionAngle - math.pi / 2; final lineStart = Offset( center.dx + (radius - 130) * math.cos(angle), center.dy + (radius - 130) * math.sin(angle), ); final lineEnd = Offset( center.dx + (radius - 22) * math.cos(angle), center.dy + (radius - 22) * math.sin(angle), ); canvas.drawLine(lineStart, lineEnd, dividerPaint); } } String _getIconText(IconData icon) { // Convert IconData to Unicode string for drawing switch (icon.codePoint) { case 0xe8f4: // Icons.visibility return String.fromCharCode(0xe8f4); case 0xe8f5: // Icons.visibility_off return String.fromCharCode(0xe8f5); case 0xe850: // Icons.account_balance_wallet return String.fromCharCode(0xe850); case 0xe151: // Icons.card_giftcard return String.fromCharCode(0xe151); case 0xe5d5: // Icons.refresh return String.fromCharCode(0xe5d5); case 0xe263: // Icons.attach_money return String.fromCharCode(0xe263); case 0xe8a1: // Icons.redeem return String.fromCharCode(0xe8a1); case 0xe57d: // Icons.monetization_on return String.fromCharCode(0xe57d); default: return String.fromCharCode(0xe87c); // Default star icon } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }