From c959e1f8be2fb04ae41939940e38b7393de2b203 Mon Sep 17 00:00:00 2001 From: Giulia Testa Date: Fri, 16 Dec 2022 11:37:24 +0100 Subject: [PATCH] created scanner overlays with relative and absolute sizes with respect to the camera size --- example/pubspec.lock | 2 +- lib/src/ui/dynamic_scanner_overlay.dart | 119 ++++++++++++++++++++++ lib/src/ui/fixed_scanner_overlay.dart | 126 ++++++++++++++++++++++++ lib/src/ui/reader_widget.dart | 3 +- lib/src/ui/scanner_overlay.dart | 117 ++-------------------- 5 files changed, 257 insertions(+), 110 deletions(-) create mode 100644 lib/src/ui/dynamic_scanner_overlay.dart create mode 100644 lib/src/ui/fixed_scanner_overlay.dart diff --git a/example/pubspec.lock b/example/pubspec.lock index 3b83a98..625a7b8 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -148,7 +148,7 @@ packages: path: ".." relative: true source: path - version: "0.8.4" + version: "0.8.5" font_awesome_flutter: dependency: "direct main" description: diff --git a/lib/src/ui/dynamic_scanner_overlay.dart b/lib/src/ui/dynamic_scanner_overlay.dart new file mode 100644 index 0000000..f3cb117 --- /dev/null +++ b/lib/src/ui/dynamic_scanner_overlay.dart @@ -0,0 +1,119 @@ +import 'package:flutter/material.dart'; + +import '../../flutter_zxing.dart'; + +class DynamicScannerOverlay extends ScannerOverlay { + + const DynamicScannerOverlay({ + super.borderColor, + super.borderWidth, + super.overlayColor, + super.borderRadius, + super.borderLength, + this.cutOutSize = 0.5 + }); + + @override + final double cutOutSize; + + @override + void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { + final double width = rect.width; + final double height = rect.height; + final double borderOffset = borderWidth / 2; + final double newBorderLength = borderLength; + final double newCutOutSize = width * cutOutSize; + + final Paint backgroundPaint = Paint() + ..color = overlayColor + ..style = PaintingStyle.fill; + + final Paint borderPaint = Paint() + ..color = borderColor + ..style = PaintingStyle.stroke + ..strokeWidth = borderWidth; + + final Paint boxPaint = Paint() + ..color = borderColor + ..style = PaintingStyle.fill + ..blendMode = BlendMode.dstOut; + + final Rect cutOutRect = Rect.fromLTWH( + rect.left + width / 2 - newCutOutSize / 2 + borderOffset, + rect.top + height / 2 - newCutOutSize / 2 + borderOffset, + newCutOutSize - borderOffset * 2, + newCutOutSize - borderOffset * 2, + ); + + canvas + ..saveLayer( + rect, + backgroundPaint, + ) + ..drawRect( + rect, + backgroundPaint, + ) + // Draw top right corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.right - newBorderLength, + cutOutRect.top, + cutOutRect.right, + cutOutRect.top + newBorderLength, + topRight: Radius.circular(borderRadius), + ), + borderPaint, + ) + // Draw top left corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.left, + cutOutRect.top, + cutOutRect.left + newBorderLength, + cutOutRect.top + newBorderLength, + topLeft: Radius.circular(borderRadius), + ), + borderPaint, + ) + // Draw bottom right corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.right - newBorderLength, + cutOutRect.bottom - newBorderLength, + cutOutRect.right, + cutOutRect.bottom, + bottomRight: Radius.circular(borderRadius), + ), + borderPaint, + ) + // Draw bottom left corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.left, + cutOutRect.bottom - newBorderLength, + cutOutRect.left + newBorderLength, + cutOutRect.bottom, + bottomLeft: Radius.circular(borderRadius), + ), + borderPaint, + ) + ..drawRRect( + RRect.fromRectAndRadius( + cutOutRect, + Radius.circular(borderRadius), + ), + boxPaint, + ) + ..restore(); + } + + @override + DynamicScannerOverlay scale(double t) { + return DynamicScannerOverlay( + borderColor: borderColor, + borderWidth: borderWidth * t, + overlayColor: overlayColor, + ); + } +} diff --git a/lib/src/ui/fixed_scanner_overlay.dart b/lib/src/ui/fixed_scanner_overlay.dart new file mode 100644 index 0000000..27a8f1d --- /dev/null +++ b/lib/src/ui/fixed_scanner_overlay.dart @@ -0,0 +1,126 @@ +import 'package:flutter/material.dart'; + +import '../../flutter_zxing.dart'; + +class FixedScannerOverlay extends ScannerOverlay { + + const FixedScannerOverlay({ + super.borderColor, + super.borderWidth, + super.overlayColor, + super.borderRadius, + super.borderLength, + this.cutOutSize = 250 + }) : assert(borderLength <= cutOutSize / 2 + borderWidth * 2, + "Border can't be larger than ${cutOutSize / 2 + borderWidth * 2}"); + + @override + final double cutOutSize; + + + @override + void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { + final double width = rect.width; + final double borderWidthSize = width / 2; + final double height = rect.height; + final double borderOffset = borderWidth / 2; + final double newBorderLength = + borderLength > cutOutSize / 2 + borderWidth * 2 + ? borderWidthSize / 2 + : borderLength; + final double newCutOutSize = + cutOutSize < width ? cutOutSize : width - borderOffset; + + final Paint backgroundPaint = Paint() + ..color = overlayColor + ..style = PaintingStyle.fill; + + final Paint borderPaint = Paint() + ..color = borderColor + ..style = PaintingStyle.stroke + ..strokeWidth = borderWidth; + + final Paint boxPaint = Paint() + ..color = borderColor + ..style = PaintingStyle.fill + ..blendMode = BlendMode.dstOut; + + final Rect cutOutRect = Rect.fromLTWH( + rect.left + width / 2 - newCutOutSize / 2 + borderOffset, + rect.top + height / 2 - newCutOutSize / 2 + borderOffset, + newCutOutSize - borderOffset * 2, + newCutOutSize - borderOffset * 2, + ); + + canvas + ..saveLayer( + rect, + backgroundPaint, + ) + ..drawRect( + rect, + backgroundPaint, + ) + // Draw top right corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.right - newBorderLength, + cutOutRect.top, + cutOutRect.right, + cutOutRect.top + newBorderLength, + topRight: Radius.circular(borderRadius), + ), + borderPaint, + ) + // Draw top left corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.left, + cutOutRect.top, + cutOutRect.left + newBorderLength, + cutOutRect.top + newBorderLength, + topLeft: Radius.circular(borderRadius), + ), + borderPaint, + ) + // Draw bottom right corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.right - newBorderLength, + cutOutRect.bottom - newBorderLength, + cutOutRect.right, + cutOutRect.bottom, + bottomRight: Radius.circular(borderRadius), + ), + borderPaint, + ) + // Draw bottom left corner + ..drawRRect( + RRect.fromLTRBAndCorners( + cutOutRect.left, + cutOutRect.bottom - newBorderLength, + cutOutRect.left + newBorderLength, + cutOutRect.bottom, + bottomLeft: Radius.circular(borderRadius), + ), + borderPaint, + ) + ..drawRRect( + RRect.fromRectAndRadius( + cutOutRect, + Radius.circular(borderRadius), + ), + boxPaint, + ) + ..restore(); + } + + @override + FixedScannerOverlay scale(double t) { + return FixedScannerOverlay( + borderColor: borderColor, + borderWidth: borderWidth * t, + overlayColor: overlayColor, + ); + } +} diff --git a/lib/src/ui/reader_widget.dart b/lib/src/ui/reader_widget.dart index 133435d..0fcae85 100644 --- a/lib/src/ui/reader_widget.dart +++ b/lib/src/ui/reader_widget.dart @@ -10,6 +10,7 @@ import 'package:flutter/material.dart'; import '../../generated_bindings.dart'; import '../logic/zxing.dart'; import '../utils/extentions.dart'; +import 'fixed_scanner_overlay.dart'; import 'scanner_overlay.dart'; class ReaderWidget extends StatefulWidget { @@ -225,7 +226,7 @@ class _ReaderWidgetState extends State Container( decoration: ShapeDecoration( shape: widget.scannerOverlay ?? - ScannerOverlay( + FixedScannerOverlay( borderColor: Theme.of(context).primaryColor, overlayColor: Colors.black45, borderRadius: 1, diff --git a/lib/src/ui/scanner_overlay.dart b/lib/src/ui/scanner_overlay.dart index 76f752e..233466a 100644 --- a/lib/src/ui/scanner_overlay.dart +++ b/lib/src/ui/scanner_overlay.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; -class ScannerOverlay extends ShapeBorder { - const ScannerOverlay({ +abstract class ScannerOverlay extends ShapeBorder { + + const ScannerOverlay ({ this.borderColor = Colors.red, this.borderWidth = 3.0, this.overlayColor = const Color.fromRGBO(0, 0, 0, 40), this.borderRadius = 0, this.borderLength = 40, - this.cutOutSize = 250, - }) : assert(borderLength <= cutOutSize / 2 + borderWidth * 2, - "Border can't be larger than ${cutOutSize / 2 + borderWidth * 2}"); + }); final Color borderColor; final double borderWidth; final Color overlayColor; final double borderRadius; final double borderLength; - final double cutOutSize; + abstract final double cutOutSize; + @override EdgeInsetsGeometry get dimensions => const EdgeInsets.all(10); @@ -53,108 +53,9 @@ class ScannerOverlay extends ShapeBorder { } @override - void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { - final double width = rect.width; - final double borderWidthSize = width / 2; - final double height = rect.height; - final double borderOffset = borderWidth / 2; - final double newBorderLength = - borderLength > cutOutSize / 2 + borderWidth * 2 - ? borderWidthSize / 2 - : borderLength; - final double newCutOutSize = - cutOutSize < width ? cutOutSize : width - borderOffset; - - final Paint backgroundPaint = Paint() - ..color = overlayColor - ..style = PaintingStyle.fill; - - final Paint borderPaint = Paint() - ..color = borderColor - ..style = PaintingStyle.stroke - ..strokeWidth = borderWidth; - - final Paint boxPaint = Paint() - ..color = borderColor - ..style = PaintingStyle.fill - ..blendMode = BlendMode.dstOut; - - final Rect cutOutRect = Rect.fromLTWH( - rect.left + width / 2 - newCutOutSize / 2 + borderOffset, - rect.top + height / 2 - newCutOutSize / 2 + borderOffset, - newCutOutSize - borderOffset * 2, - newCutOutSize - borderOffset * 2, - ); - - canvas - ..saveLayer( - rect, - backgroundPaint, - ) - ..drawRect( - rect, - backgroundPaint, - ) - // Draw top right corner - ..drawRRect( - RRect.fromLTRBAndCorners( - cutOutRect.right - newBorderLength, - cutOutRect.top, - cutOutRect.right, - cutOutRect.top + newBorderLength, - topRight: Radius.circular(borderRadius), - ), - borderPaint, - ) - // Draw top left corner - ..drawRRect( - RRect.fromLTRBAndCorners( - cutOutRect.left, - cutOutRect.top, - cutOutRect.left + newBorderLength, - cutOutRect.top + newBorderLength, - topLeft: Radius.circular(borderRadius), - ), - borderPaint, - ) - // Draw bottom right corner - ..drawRRect( - RRect.fromLTRBAndCorners( - cutOutRect.right - newBorderLength, - cutOutRect.bottom - newBorderLength, - cutOutRect.right, - cutOutRect.bottom, - bottomRight: Radius.circular(borderRadius), - ), - borderPaint, - ) - // Draw bottom left corner - ..drawRRect( - RRect.fromLTRBAndCorners( - cutOutRect.left, - cutOutRect.bottom - newBorderLength, - cutOutRect.left + newBorderLength, - cutOutRect.bottom, - bottomLeft: Radius.circular(borderRadius), - ), - borderPaint, - ) - ..drawRRect( - RRect.fromRectAndRadius( - cutOutRect, - Radius.circular(borderRadius), - ), - boxPaint, - ) - ..restore(); - } + void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}); @override - ShapeBorder scale(double t) { - return ScannerOverlay( - borderColor: borderColor, - borderWidth: borderWidth, - overlayColor: overlayColor, - ); - } + ScannerOverlay scale(double t); + }