From facdea6185b276a73d54e28a9941265e572188cb Mon Sep 17 00:00:00 2001 From: otsmr Date: Thu, 23 Jan 2025 22:25:09 +0100 Subject: [PATCH] camera does work ok --- lib/src/views/camera_preview_view.dart | 310 +++++++++++++++++-------- 1 file changed, 215 insertions(+), 95 deletions(-) diff --git a/lib/src/views/camera_preview_view.dart b/lib/src/views/camera_preview_view.dart index 75ca240..4072209 100644 --- a/lib/src/views/camera_preview_view.dart +++ b/lib/src/views/camera_preview_view.dart @@ -1,116 +1,236 @@ // import 'package:camera/camera.dart'; // import 'camera_editor_view.dart'; // import 'package:flutter/gestures.dart'; +import 'package:camerawesome/pigeon.dart'; import 'package:flutter/material.dart'; +import 'dart:math'; import 'package:camerawesome/camerawesome_plugin.dart'; -class CameraPreviewView extends StatelessWidget { +class CameraPreviewView extends StatefulWidget { const CameraPreviewView({super.key}); @override - Widget build(BuildContext context) { - return const MaterialApp( - title: 'Custom CamerAwesome UI', - home: CameraPage(), - ); - } + State createState() => _CameraPreviewViewState(); } -class CameraPage extends StatelessWidget { - const CameraPage({super.key}); +class _CameraPreviewViewState extends State { + double _lastZoom = 1; + double _basePanY = 0; + + @override + void initState() { + super.initState(); + } @override Widget build(BuildContext context) { - return Scaffold( - body: CameraAwesomeBuilder.awesome( - saveConfig: SaveConfig.photo(), - sensorConfig: SensorConfig.single( - sensor: Sensor.position(SensorPosition.back), - aspectRatio: CameraAspectRatios.ratio_1_1, - ), - previewFit: CameraPreviewFit.contain, - previewPadding: const EdgeInsets.only(left: 150, top: 100), - previewAlignment: Alignment.topRight, - // Buttons of CamerAwesome UI will use this theme - theme: AwesomeTheme( - bottomActionsBackgroundColor: Colors.cyan.withAlpha(150), - buttonTheme: AwesomeButtonTheme( - backgroundColor: Colors.cyan.withAlpha(150), - iconSize: 20, - foregroundColor: Colors.white, - padding: const EdgeInsets.all(16), - // Tap visual feedback (ripple, bounce...) - buttonBuilder: (child, onTap) { - return ClipOval( - child: Material( - color: Colors.transparent, - shape: const CircleBorder(), - child: InkWell( - splashColor: Colors.cyan, - highlightColor: Colors.cyan.withAlpha(150), - onTap: onTap, - child: child, + return Padding( + padding: EdgeInsets.only(top: 50, bottom: 30, left: 5, right: 5), + child: ClipRRect( + borderRadius: BorderRadius.circular(22), + child: CameraAwesomeBuilder.custom( + progressIndicator: Container(), + builder: (cameraState, preview) { + return Container( + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Positioned.fill( + child: GestureDetector( + onPanStart: (details) async { + setState(() { + _basePanY = details.localPosition.dy; + }); + }, + onPanUpdate: (details) async { + var diff = _basePanY - details.localPosition.dy; + if (diff > 200) diff = 200; + if (diff < 0) diff = 0; + var tmp = (diff / 200 * 50).toInt() / 50; + if (tmp != _lastZoom) { + cameraState.sensorConfig.setZoom(tmp); + setState(() { + _lastZoom = tmp; + }); + } + }, + ), ), - ), - ); - }, - ), - ), - topActionsBuilder: (state) => AwesomeTopActions( - padding: EdgeInsets.zero, - state: state, - children: [ - Expanded( - child: AwesomeFilterWidget( - state: state, - filterListPosition: FilterListPosition.aboveButton, - filterListPadding: const EdgeInsets.only(top: 8), - ), - ), - ], - ), - middleContentBuilder: (state) { - return Column( - children: [ - const Spacer(), - Builder(builder: (context) { - return Container( - color: AwesomeThemeProvider.of(context) - .theme - .bottomActionsBackgroundColor, - child: const Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: EdgeInsets.only(bottom: 10, top: 10), - child: Text( - "Take your best shot!", - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.italic, - ), + Positioned( + bottom: 30, + left: 0, + right: 0, + child: Align( + alignment: Alignment.bottomCenter, + child: Column( + children: [ + AwesomeZoomSelector(state: cameraState + // controller: _controller, + ), + const SizedBox(height: 30), + GestureDetector( + onTap: () async { + cameraState.when( + onPhotoMode: (picState) => + picState.takePhoto()); + // await takePicture(); + }, + onLongPress: () async {}, + child: Align( + alignment: Alignment.center, + child: Container( + height: 100, + width: 100, + clipBehavior: Clip.antiAliasWithSaveLayer, + padding: const EdgeInsets.all(2), + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + width: 7, + color: Colors.white, + ), + ), + ), + ), + ), + ], ), ), ), - ); - }), - ], - ); - }, - bottomActionsBuilder: (state) => AwesomeBottomActions( - state: state, - left: AwesomeFlashButton( - state: state, - ), - right: AwesomeCameraSwitchButton( - state: state, - scale: 1.0, - onSwitchTap: (state) { - state.switchCameraSensor( - aspectRatio: state.sensorConfig.aspectRatio, - ); - }, - ), + ], + ), + ); + }, + saveConfig: SaveConfig.photoAndVideo(), + previewPadding: const EdgeInsets.all(10), + // onPreviewTapBuilder: (state) => OnPreviewTap( + // onTap: (Offset position, PreviewSize flutterPreviewSize, + // PreviewSize pixelPreviewSize) { + // state.when(onPhotoMode: (picState) => picState.takePhoto()); + // }, + // onTapPainter: (tapPosition) => TweenAnimationBuilder( + // key: ValueKey(tapPosition), + // tween: Tween(begin: 1.0, end: 0.0), + // duration: const Duration(milliseconds: 500), + // builder: (context, anim, child) { + // return Transform.rotate( + // angle: anim * 2 * pi, + // child: Transform.scale( + // scale: 4 * anim, + // child: child, + // ), + // ); + // }, + // child: const Icon( + // Icons.camera, + // color: Colors.white, + // ), + // ), + // ), + ), + ), + ); + } +} + +String beautifulZoomScale(double scale) { + var tmp = scale.toStringAsFixed(1); + if (tmp[0] == "0") { + tmp = tmp.substring(1, tmp.length); + } + return tmp; +} + +class CameraZoomButtons extends StatefulWidget { + const CameraZoomButtons( + {super.key, + required this.isFront, + required this.updateScaleFactor, + required this.scaleFactor}); + + final bool isFront; + final double scaleFactor; + final Function updateScaleFactor; + + @override + State createState() => _CameraZoomButtonsState(); +} + +class _CameraZoomButtonsState extends State { + @override + Widget build(BuildContext context) { + final zoomButtonStyle = TextButton.styleFrom( + padding: EdgeInsets.zero, + foregroundColor: Colors.white, + minimumSize: Size(40, 40), + alignment: Alignment.center, + tapTargetSize: MaterialTapTargetSize.shrinkWrap); + + final zoomTextStyle = TextStyle(fontSize: 13); + return ClipRRect( + borderRadius: BorderRadius.circular(40.0), + child: Container( + color: const Color.fromARGB(90, 0, 0, 0), + child: Row( + children: widget.isFront + ? [] + : [ + TextButton( + style: zoomButtonStyle, + onPressed: () async { + // var level = await widget.controller.getMinZoomLevel(); + // widget.updateScaleFactor(level); + }, + child: Text(""), + // child: FutureBuilder( + // future: widget.controller.getMinZoomLevel(), + // builder: (context, snap) { + // if (snap.hasData) { + // var minLevel = + // beautifulZoomScale(snap.data!.toDouble()); + // var currentLevel = + // beautifulZoomScale(widget.scaleFactor); + // return Text( + // widget.scaleFactor < 1 + // ? "${currentLevel}x" + // : "${minLevel}x", + // style: zoomTextStyle, + // ); + // } else { + // return Text(""); + // } + // }), + ), + TextButton( + style: zoomButtonStyle, + onPressed: () { + widget.updateScaleFactor(1.0); + }, + child: Text( + widget.scaleFactor >= 1 + ? "${beautifulZoomScale(widget.scaleFactor)}x" + : "1.0x", + style: zoomTextStyle, + )), + TextButton( + style: zoomButtonStyle, + onPressed: () async { + // var level = await widget.controller.getMaxZoomLevel(); + // widget.updateScaleFactor(level); + }, + child: Text(""), + // child: FutureBuilder( + // future: widget.controller.getMaxZoomLevel(), + // builder: (context, snap) { + // if (snap.hasData) { + // var maxLevel = snap.data?.toInt(); + // return Text("${maxLevel}x", style: zoomTextStyle); + // } else { + // return Text(""); + // } + // }), + ) + ], ), ), );