allow to zoom more than 2x

This commit is contained in:
otsmr 2025-03-22 15:42:05 +01:00
parent 01a24cc6dc
commit 7e4787f0da
3 changed files with 98 additions and 92 deletions

View file

@ -30,13 +30,15 @@ class _CameraZoomButtonsState extends State<CameraZoomButtons> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var zoomButtonStyle = TextButton.styleFrom( var zoomButtonStyle = TextButton.styleFrom(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
foregroundColor: Colors.white, foregroundColor: Colors.white,
minimumSize: Size(40, 40), minimumSize: Size(40, 40),
alignment: Alignment.center, alignment: Alignment.center,
tapTargetSize: MaterialTapTargetSize.shrinkWrap); tapTargetSize: MaterialTapTargetSize.shrinkWrap,
);
final zoomTextStyle = TextStyle(fontSize: 13); final zoomTextStyle = TextStyle(fontSize: 13);
final isMiddleFocused = widget.scaleFactor >= 1 && widget.scaleFactor < 2;
return Center( return Center(
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(40.0), borderRadius: BorderRadius.circular(40.0),
@ -46,43 +48,54 @@ class _CameraZoomButtonsState extends State<CameraZoomButtons> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
TextButton( TextButton(
style: zoomButtonStyle, style: zoomButtonStyle.copyWith(
foregroundColor: WidgetStateProperty.all(
(widget.scaleFactor < 1) ? Colors.yellow : Colors.white,
),
),
onPressed: () async { onPressed: () async {
var level = await widget.controller.getMinZoomLevel(); var level = await widget.controller.getMinZoomLevel();
widget.updateScaleFactor(level); widget.updateScaleFactor(level);
}, },
child: FutureBuilder( child: FutureBuilder(
future: widget.controller.getMinZoomLevel(), future: widget.controller.getMinZoomLevel(),
builder: (context, snap) { builder: (context, snap) {
if (snap.hasData) { if (snap.hasData) {
var minLevel = var minLevel = beautifulZoomScale(snap.data!.toDouble());
beautifulZoomScale(snap.data!.toDouble()); var currentLevel = beautifulZoomScale(widget.scaleFactor);
var currentLevel = return Text(
beautifulZoomScale(widget.scaleFactor); widget.scaleFactor < 1
return Text( ? "${currentLevel}x"
widget.scaleFactor < 1 : "${minLevel}x",
? "${currentLevel}x" style: zoomTextStyle,
: "${minLevel}x", );
style: zoomTextStyle, } else {
); return Text("");
} else { }
return Text(""); },
} ),
}),
), ),
TextButton( TextButton(
style: zoomButtonStyle, style: zoomButtonStyle.copyWith(
foregroundColor: WidgetStateProperty.all(
isMiddleFocused ? Colors.yellow : Colors.white,
),
),
onPressed: () { onPressed: () {
widget.updateScaleFactor(1.0); widget.updateScaleFactor(1.0);
}, },
child: Text( child: Text(
(widget.scaleFactor >= 1 && widget.scaleFactor < 2) (isMiddleFocused)
? "${beautifulZoomScale(widget.scaleFactor)}x" ? "${beautifulZoomScale(widget.scaleFactor)}x"
: "1.0x", : "1.0x",
style: zoomTextStyle, style: zoomTextStyle,
)), )),
TextButton( TextButton(
style: zoomButtonStyle, style: zoomButtonStyle.copyWith(
foregroundColor: WidgetStateProperty.all(
(widget.scaleFactor >= 2) ? Colors.yellow : Colors.white,
),
),
onPressed: () async { onPressed: () async {
var level = min(await widget.controller.getMaxZoomLevel(), 2) var level = min(await widget.controller.getMaxZoomLevel(), 2)
.toDouble(); .toDouble();
@ -92,8 +105,13 @@ class _CameraZoomButtonsState extends State<CameraZoomButtons> {
future: widget.controller.getMaxZoomLevel(), future: widget.controller.getMaxZoomLevel(),
builder: (context, snap) { builder: (context, snap) {
if (snap.hasData) { if (snap.hasData) {
var maxLevel = min((snap.data?.toInt())!, 2); var maxLevel = max(
return Text("${maxLevel}x", style: zoomTextStyle); min((snap.data?.toInt())!, 2),
widget.scaleFactor,
);
return Text(
"${beautifulZoomScale(maxLevel.toDouble())}x",
style: zoomTextStyle);
} else { } else {
return Text(""); return Text("");
} }

View file

@ -54,6 +54,8 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
bool showSelfieFlash = false; bool showSelfieFlash = false;
int cameraId = 0; int cameraId = 0;
bool isZoomAble = false; bool isZoomAble = false;
double basePanY = 0;
double baseScaleFactor = 0;
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
late CameraController controller; late CameraController controller;
@ -105,6 +107,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
} }
Future<void> updateScaleFactor(double newScale) async { Future<void> updateScaleFactor(double newScale) async {
if (scaleFactor == newScale) return;
var minFactor = await controller.getMinZoomLevel(); var minFactor = await controller.getMinZoomLevel();
var maxFactor = await controller.getMaxZoomLevel(); var maxFactor = await controller.getMaxZoomLevel();
if (newScale < minFactor) { if (newScale < minFactor) {
@ -128,6 +131,9 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
super.dispose(); super.dispose();
} }
bool get isFront =>
controller.description.lensDirection == CameraLensDirection.front;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (cameraId >= gCameras.length) { if (cameraId >= gCameras.length) {
@ -145,49 +151,45 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
(controller.value.isInitialized) (controller.value.isInitialized)
? Positioned.fill( ? Positioned.fill(
child: Screenshot( child: Screenshot(
controller: screenshotController, controller: screenshotController,
child: AspectRatio( child: AspectRatio(
aspectRatio: 9 / 16, aspectRatio: 9 / 16,
child: ClipRect( child: ClipRect(
child: FittedBox( child: FittedBox(
fit: BoxFit.cover, fit: BoxFit.cover,
child: SizedBox( child: SizedBox(
width: controller.value.previewSize!.height, width: controller.value.previewSize!.height,
height: controller.value.previewSize!.width, height: controller.value.previewSize!.width,
child: CameraPreview(controller), child: CameraPreview(controller),
),
), ),
), ),
)), ),
),
),
) )
: Container(), : Container(),
Positioned.fill( Positioned.fill(
child: GestureDetector( child: GestureDetector(
onPanStart: (details) async { onPanStart: (details) async {
// if (cameraState.sensorConfig.sensors.first.position == if (isFront) {
// SensorPosition.front) { return;
// return; }
// } setState(() {
// setState(() { basePanY = details.localPosition.dy;
// _basePanY = details.localPosition.dy; baseScaleFactor = scaleFactor;
// }); });
}, },
onPanUpdate: (details) async { onPanUpdate: (details) async {
// if (cameraState.sensorConfig.sensors.first.position == if (isFront) {
// SensorPosition.front) { return;
// return; }
// } var diff = basePanY - details.localPosition.dy;
// var diff = _basePanY - details.localPosition.dy; if (diff > 200) diff = 200;
// if (diff > 200) diff = 200; if (diff < -200) diff = -200;
// if (diff < 0) diff = 0; var tmp = (diff / 200 * (7 * 2)).toInt() / 2;
// var tmp = (diff / 200 * 50).toInt() / 50; tmp = baseScaleFactor + tmp;
// if (tmp != _lastZoom) { if (tmp < 1) tmp = 1;
// cameraState.sensorConfig.setZoom(tmp); updateScaleFactor(tmp);
// setState(() {
// (tmp);
// _lastZoom = tmp;
// });
// }
}, },
onDoubleTap: () async { onDoubleTap: () async {
selectCamera((cameraId + 1) % 2); selectCamera((cameraId + 1) % 2);
@ -246,10 +248,9 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
children: [ children: [
if (controller.value.isInitialized && if (controller.value.isInitialized &&
isZoomAble && isZoomAble &&
controller.description.lensDirection != !isFront)
CameraLensDirection.front)
SizedBox( SizedBox(
width: 150, width: 120,
child: CameraZoomButtons( child: CameraZoomButtons(
key: widget.key, key: widget.key,
scaleFactor: scaleFactor, scaleFactor: scaleFactor,
@ -261,8 +262,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
if (isFlashOn) { if (isFlashOn) {
if (controller.description.lensDirection == if (isFront) {
CameraLensDirection.front) {
setState(() { setState(() {
showSelfieFlash = true; showSelfieFlash = true;
}); });

View file

@ -53,37 +53,26 @@ class _ProfileViewState extends State<ProfileView> {
body: ListView( body: ListView(
physics: BouncingScrollPhysics(), physics: BouncingScrollPhysics(),
children: <Widget>[ children: <Widget>[
SizedBox( SizedBox(height: 25),
height: 25,
),
AvatarMakerAvatar( AvatarMakerAvatar(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
radius: 80, radius: 80,
), ),
SizedBox( SizedBox(height: 10),
height: 10, Center(
), child: SizedBox(
Row( height: 35,
children: [ child: ElevatedButton.icon(
Spacer(flex: 2), icon: Icon(Icons.edit),
Expanded( label: Text(context.lang.settingsProfileCustomizeAvatar),
flex: 3, onPressed: () => Navigator.push(
child: SizedBox( context,
height: 35, MaterialPageRoute(
child: ElevatedButton.icon( builder: (context) => ModifyAvatar(),
icon: Icon(Icons.edit),
label: Text(context.lang.settingsProfileCustomizeAvatar),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ModifyAvatar(),
),
),
), ),
), ),
), ),
Spacer(flex: 2), ),
],
), ),
SizedBox(height: 20), SizedBox(height: 20),
const Divider(), const Divider(),
@ -94,7 +83,6 @@ class _ProfileViewState extends State<ProfileView> {
onTap: () async { onTap: () async {
final displayName = final displayName =
await showDisplayNameChangeDialog(context, user!.displayName); await showDisplayNameChangeDialog(context, user!.displayName);
if (context.mounted && displayName != null && displayName != "") { if (context.mounted && displayName != null && displayName != "") {
updateUserDisplayname(displayName); updateUserDisplayname(displayName);
} }