/// 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; } }