From 24fd6f9e2d6be3d9c3fff5196d4e51e1239cb0e5 Mon Sep 17 00:00:00 2001 From: Khoren Markosyan Date: Mon, 6 Jun 2022 14:31:43 +0400 Subject: [PATCH] added pinch to zoom support --- lib/reader_widget.dart | 57 ++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/lib/reader_widget.dart b/lib/reader_widget.dart index c00433e..40682f7 100644 --- a/lib/reader_widget.dart +++ b/lib/reader_widget.dart @@ -18,7 +18,9 @@ class ReaderWidget extends StatefulWidget { this.codeFormat = Format.Any, this.beep = true, this.showCroppingRect = true, + this.scannerOverlay, this.showFlashlight = true, + this.allowPinchZoom = true, this.scanDelay = const Duration(milliseconds: 1000), // 1000ms delay this.cropPercent = 0.5, // 50% of the screen this.resolution = ResolutionPreset.high, @@ -29,7 +31,9 @@ class ReaderWidget extends StatefulWidget { final int codeFormat; final bool beep; final bool showCroppingRect; + final ScannerOverlay? scannerOverlay; final bool showFlashlight; + final bool allowPinchZoom; final Duration scanDelay; final double cropPercent; final ResolutionPreset resolution; @@ -44,6 +48,11 @@ class _ReaderWidgetState extends State CameraController? controller; var _cameraOn = false; + double _zoom = 1.0; + double _scaleFactor = 1.0; + double _maxZoomLevel = 1.0; + double _minZoomLevel = 1.0; + bool isAndroid() => Theme.of(context).platform == TargetPlatform.android; // true when code detecting is ongoing @@ -111,16 +120,21 @@ class _ReaderWidgetState extends State imageFormatGroup: isAndroid() ? ImageFormatGroup.yuv420 : ImageFormatGroup.bgra8888, ); - + final CameraController? cameraController = controller; + if (cameraController == null) { + return; + } try { - await controller?.initialize(); - await controller?.setFlashMode(FlashMode.off); - controller?.startImageStream(processCameraImage); + await cameraController.initialize(); + await cameraController.setFlashMode(FlashMode.off); + _maxZoomLevel = await cameraController.getMaxZoomLevel(); + _minZoomLevel = await cameraController.getMinZoomLevel(); + cameraController.startImageStream(processCameraImage); } on CameraException catch (e) { debugPrint('${e.code}: ${e.description}'); } - controller?.addListener(() { + cameraController.addListener(() { if (mounted) setState(() {}); }); @@ -129,7 +143,7 @@ class _ReaderWidgetState extends State setState(() {}); } - widget.onControllerCreated?.call(controller); + widget.onControllerCreated?.call(cameraController); } processCameraImage(CameraImage image) async { @@ -208,19 +222,31 @@ class _ReaderWidgetState extends State if (widget.showCroppingRect) Container( decoration: ShapeDecoration( - shape: ScannerOverlay( - borderColor: Theme.of(context).primaryColor, - overlayColor: const Color.fromRGBO(0, 0, 0, 0.5), - borderRadius: 1, - borderLength: 16, - borderWidth: 8, - cutOutSize: cropSize, - ), + shape: widget.scannerOverlay ?? + ScannerOverlay( + borderColor: Theme.of(context).primaryColor, + overlayColor: Colors.black45, + borderRadius: 1, + borderLength: 16, + borderWidth: 8, + cutOutSize: cropSize, + ), ), ), + if (widget.allowPinchZoom) + GestureDetector( + onScaleStart: (details) { + _zoom = _scaleFactor; + }, + onScaleUpdate: (details) { + _scaleFactor = + (_zoom * details.scale).clamp(_minZoomLevel, _maxZoomLevel); + cameraController.setZoomLevel(_scaleFactor); + }, + ), if (widget.showFlashlight) Positioned( - top: 20, + bottom: 20, left: 20, child: FloatingActionButton( onPressed: () { @@ -237,7 +263,6 @@ class _ReaderWidgetState extends State cameraController.setFlashMode(mode); setState(() {}); }, - mini: true, backgroundColor: Colors.black26, child: Icon(_flashIcon(cameraController)), ),