188 lines
6.8 KiB
Dart
188 lines
6.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'dart:math' as math;
|
|
|
|
class ZoneMapDialog extends StatelessWidget {
|
|
final String playerName;
|
|
final bool isMake;
|
|
final Function(String zone, int points, double relativeX, double relativeY) onZoneSelected;
|
|
|
|
const ZoneMapDialog({
|
|
super.key,
|
|
required this.playerName,
|
|
required this.isMake,
|
|
required this.onZoneSelected,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final Color headerColor = const Color(0xFFE88F15);
|
|
final Color yellowBackground = const Color(0xFFDFAB00);
|
|
|
|
final double screenHeight = MediaQuery.of(context).size.height;
|
|
final double dialogHeight = screenHeight * 0.95;
|
|
final double dialogWidth = dialogHeight * 1.0;
|
|
|
|
return Dialog(
|
|
backgroundColor: yellowBackground,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
clipBehavior: Clip.antiAlias,
|
|
insetPadding: const EdgeInsets.all(10),
|
|
child: SizedBox(
|
|
height: dialogHeight,
|
|
width: dialogWidth,
|
|
child: Column(
|
|
children: [
|
|
// CABEÇALHO
|
|
Container(
|
|
height: 40,
|
|
color: headerColor,
|
|
width: double.infinity,
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
Text(
|
|
isMake ? "Lançamento de $playerName (Marcou)" : "Lançamento de $playerName (Falhou)",
|
|
style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.bold),
|
|
),
|
|
Positioned(
|
|
right: 8,
|
|
child: InkWell(
|
|
onTap: () => Navigator.pop(context),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(4),
|
|
decoration: const BoxDecoration(color: Colors.white, shape: BoxShape.circle),
|
|
child: Icon(Icons.close, color: headerColor, size: 16),
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
// MAPA INTERATIVO
|
|
Expanded(
|
|
child: LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
return GestureDetector(
|
|
onTapUp: (details) => _calculateAndReturnZone(context, details.localPosition, constraints.biggest),
|
|
child: CustomPaint(
|
|
size: Size(constraints.maxWidth, constraints.maxHeight),
|
|
painter: DebugPainter(),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _calculateAndReturnZone(BuildContext context, Offset tap, Size size) {
|
|
final double w = size.width;
|
|
final double h = size.height;
|
|
final double x = tap.dx;
|
|
final double y = tap.dy;
|
|
final double basketX = w / 2;
|
|
|
|
// MESMAS MEDIDAS DO PAINTER
|
|
final double margin = w * 0.10;
|
|
final double length = h * 0.35;
|
|
final double larguraDoArco = (w / 2) - margin;
|
|
final double alturaDoArco = larguraDoArco * 0.30;
|
|
final double totalArcoHeight = alturaDoArco * 4;
|
|
|
|
String zone = "Meia Distância";
|
|
int pts = 2;
|
|
|
|
// 1. TESTE DE 3 PONTOS
|
|
bool is3 = false;
|
|
if (y < length) {
|
|
if (x < margin || x > w - margin) is3 = true;
|
|
} else {
|
|
double dx = x - basketX;
|
|
double dy = y - length;
|
|
double ellipse = (dx * dx) / (larguraDoArco * larguraDoArco) + (dy * dy) / (math.pow(totalArcoHeight / 2, 2));
|
|
if (ellipse > 1.0) is3 = true;
|
|
}
|
|
|
|
if (is3) {
|
|
pts = 3;
|
|
double angle = math.atan2(y - length, x - basketX);
|
|
if (y < length) {
|
|
zone = (x < w / 2) ? "Canto Esquerdo" : "Canto Direito";
|
|
} else if (angle > 2.35) {
|
|
zone = "Ala Esquerda";
|
|
} else if (angle < 0.78) {
|
|
zone = "Ala Direita";
|
|
} else {
|
|
zone = "Topo (3pts)";
|
|
}
|
|
} else {
|
|
// 2. TESTE DE GARRAFÃO
|
|
final double pW = w * 0.28;
|
|
final double pH = h * 0.38;
|
|
if (x > basketX - pW / 2 && x < basketX + pW / 2 && y < pH) {
|
|
zone = "Garrafão";
|
|
}
|
|
}
|
|
|
|
onZoneSelected(zone, pts, x / w, y / h);
|
|
Navigator.pop(context);
|
|
}
|
|
}
|
|
|
|
class DebugPainter extends CustomPainter {
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final double w = size.width;
|
|
final double h = size.height;
|
|
final double basketX = w / 2;
|
|
|
|
final Paint whiteStroke = Paint()..color = Colors.white..style = PaintingStyle.stroke..strokeWidth = 2.0;
|
|
final Paint blackStroke = Paint()..color = Colors.black87..style = PaintingStyle.stroke..strokeWidth = 2.0;
|
|
|
|
final double margin = w * 0.10;
|
|
final double length = h * 0.35;
|
|
final double larguraDoArco = (w / 2) - margin;
|
|
final double alturaDoArco = larguraDoArco * 0.30;
|
|
final double totalArcoHeight = alturaDoArco * 4;
|
|
|
|
// 3 PONTOS (BRANCO)
|
|
canvas.drawLine(Offset(margin, 0), Offset(margin, length), whiteStroke);
|
|
canvas.drawLine(Offset(w - margin, 0), Offset(w - margin, length), whiteStroke);
|
|
canvas.drawLine(Offset(0, length), Offset(margin, length), whiteStroke);
|
|
canvas.drawLine(Offset(w - margin, length), Offset(w, length), whiteStroke);
|
|
canvas.drawArc(Rect.fromCenter(center: Offset(basketX, length), width: larguraDoArco * 2, height: totalArcoHeight), 0, math.pi, false, whiteStroke);
|
|
|
|
// DIVISÕES 45º (BRANCO)
|
|
double sXL = basketX + (larguraDoArco * math.cos(math.pi * 0.75));
|
|
double sYL = length + ((totalArcoHeight / 2) * math.sin(math.pi * 0.75));
|
|
double sXR = basketX + (larguraDoArco * math.cos(math.pi * 0.25));
|
|
double sYR = length + ((totalArcoHeight / 2) * math.sin(math.pi * 0.25));
|
|
canvas.drawLine(Offset(sXL, sYL), Offset(0, h * 0.85), whiteStroke);
|
|
canvas.drawLine(Offset(sXR, sYR), Offset(w, h * 0.85), whiteStroke);
|
|
|
|
// GARRAFÃO E MEIO CAMPO (PRETO)
|
|
final double pW = w * 0.28;
|
|
final double pH = h * 0.38;
|
|
canvas.drawRect(Rect.fromLTWH(basketX - pW / 2, 0, pW, pH), blackStroke);
|
|
final double ftR = pW / 2;
|
|
canvas.drawArc(Rect.fromCircle(center: Offset(basketX, pH), radius: ftR), 0, math.pi, false, blackStroke);
|
|
|
|
// Tracejado
|
|
const int dashCount = 10;
|
|
for (int i = 0; i < dashCount; i++) {
|
|
canvas.drawArc(Rect.fromCircle(center: Offset(basketX, pH), radius: ftR), math.pi + (i * 2 * (math.pi / 20)), math.pi / 20, false, blackStroke);
|
|
}
|
|
|
|
canvas.drawArc(Rect.fromCircle(center: Offset(basketX, h), radius: w * 0.12), math.pi, math.pi, false, blackStroke);
|
|
|
|
// CESTO
|
|
canvas.drawCircle(Offset(basketX, h * 0.12), w * 0.02, blackStroke);
|
|
canvas.drawLine(Offset(basketX - w * 0.08, h * 0.12 - 5), Offset(basketX + w * 0.08, h * 0.12 - 5), blackStroke);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(CustomPainter old) => false;
|
|
} |