Files
impact/lib/features/crop/widgets/crop_overlay.dart

204 lines
5.2 KiB
Dart

/// Overlay visuel pour le recadrage d'image.
///
/// Affiche un masque semi-transparent avec une zone carrée transparente
/// au centre pour indiquer la zone de recadrage.
library;
import 'package:flutter/material.dart';
class CropOverlay extends StatelessWidget {
/// Taille du carré de recadrage (côté en pixels)
final double cropSize;
/// Afficher la grille des tiers
final bool showGrid;
const CropOverlay({super.key, required this.cropSize, this.showGrid = true});
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size.infinite,
painter: _CropOverlayPainter(cropSize: cropSize, showGrid: showGrid),
);
}
}
class _CropOverlayPainter extends CustomPainter {
final double cropSize;
final bool showGrid;
_CropOverlayPainter({required this.cropSize, required this.showGrid});
@override
void paint(Canvas canvas, Size size) {
// Calculer la position du carré centré
final cropRect = Rect.fromCenter(
center: Offset(size.width / 2, size.height / 2),
width: cropSize,
height: cropSize,
);
// Dessiner le masque semi-transparent
final maskPaint = Paint()
..color = Colors.black.withValues(alpha: 0.6)
..style = PaintingStyle.fill;
// Créer un path pour le masque (tout sauf le carré central)
final maskPath = Path()
..addRect(Rect.fromLTWH(0, 0, size.width, size.height))
..addRect(cropRect)
..fillType = PathFillType.evenOdd;
canvas.drawPath(maskPath, maskPaint);
// Dessiner la bordure du carré de recadrage
final borderPaint = Paint()
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 2;
canvas.drawRect(cropRect, borderPaint);
// Dessiner les coins accentués
_drawCorners(canvas, cropRect);
// Dessiner la grille des tiers si activée
if (showGrid) {
_drawGrid(canvas, cropRect);
}
// Dessiner le point central (croix)
_drawCenterPoint(canvas, cropRect);
}
void _drawCorners(Canvas canvas, Rect rect) {
final cornerPaint = Paint()
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 4
..strokeCap = StrokeCap.round;
const cornerLength = 20.0;
// Coin supérieur gauche
canvas.drawLine(
Offset(rect.left, rect.top + cornerLength),
Offset(rect.left, rect.top),
cornerPaint,
);
canvas.drawLine(
Offset(rect.left, rect.top),
Offset(rect.left + cornerLength, rect.top),
cornerPaint,
);
// Coin supérieur droit
canvas.drawLine(
Offset(rect.right - cornerLength, rect.top),
Offset(rect.right, rect.top),
cornerPaint,
);
canvas.drawLine(
Offset(rect.right, rect.top),
Offset(rect.right, rect.top + cornerLength),
cornerPaint,
);
// Coin inférieur gauche
canvas.drawLine(
Offset(rect.left, rect.bottom - cornerLength),
Offset(rect.left, rect.bottom),
cornerPaint,
);
canvas.drawLine(
Offset(rect.left, rect.bottom),
Offset(rect.left + cornerLength, rect.bottom),
cornerPaint,
);
// Coin inférieur droit
canvas.drawLine(
Offset(rect.right - cornerLength, rect.bottom),
Offset(rect.right, rect.bottom),
cornerPaint,
);
canvas.drawLine(
Offset(rect.right, rect.bottom),
Offset(rect.right, rect.bottom - cornerLength),
cornerPaint,
);
}
void _drawGrid(Canvas canvas, Rect rect) {
final gridPaint = Paint()
..color = Colors.white.withValues(alpha: 0.4)
..style = PaintingStyle.stroke
..strokeWidth = 1;
final thirdWidth = rect.width / 3;
final thirdHeight = rect.height / 3;
// Lignes verticales
canvas.drawLine(
Offset(rect.left + thirdWidth, rect.top),
Offset(rect.left + thirdWidth, rect.bottom),
gridPaint,
);
canvas.drawLine(
Offset(rect.left + thirdWidth * 2, rect.top),
Offset(rect.left + thirdWidth * 2, rect.bottom),
gridPaint,
);
// Lignes horizontales
canvas.drawLine(
Offset(rect.left, rect.top + thirdHeight),
Offset(rect.right, rect.top + thirdHeight),
gridPaint,
);
canvas.drawLine(
Offset(rect.left, rect.top + thirdHeight * 2),
Offset(rect.right, rect.top + thirdHeight * 2),
gridPaint,
);
}
void _drawCenterPoint(Canvas canvas, Rect rect) {
final centerPaint = Paint()
..color = Colors.white.withValues(alpha: 0.8)
..style = PaintingStyle.stroke
..strokeWidth = 2;
const size = 10.0;
final centerX = rect.center.dx;
final centerY = rect.center.dy;
// Ligne horizontale
canvas.drawLine(
Offset(centerX - size, centerY),
Offset(centerX + size, centerY),
centerPaint,
);
// Ligne verticale
canvas.drawLine(
Offset(centerX, centerY - size),
Offset(centerX, centerY + size),
centerPaint,
);
// Petit cercle central pour précision (optionnel, mais aide à viser)
canvas.drawCircle(
rect.center,
2,
Paint()..color = Colors.red.withValues(alpha: 0.6),
);
}
@override
bool shouldRepaint(covariant _CropOverlayPainter oldDelegate) {
return cropSize != oldDelegate.cropSize || showGrid != oldDelegate.showGrid;
}
}