mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:08:40 +00:00
camera does work ok
This commit is contained in:
parent
931e9c0666
commit
facdea6185
1 changed files with 215 additions and 95 deletions
|
|
@ -1,116 +1,236 @@
|
||||||
// import 'package:camera/camera.dart';
|
// import 'package:camera/camera.dart';
|
||||||
// import 'camera_editor_view.dart';
|
// import 'camera_editor_view.dart';
|
||||||
// import 'package:flutter/gestures.dart';
|
// import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:camerawesome/pigeon.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'dart:math';
|
||||||
import 'package:camerawesome/camerawesome_plugin.dart';
|
import 'package:camerawesome/camerawesome_plugin.dart';
|
||||||
|
|
||||||
class CameraPreviewView extends StatelessWidget {
|
class CameraPreviewView extends StatefulWidget {
|
||||||
const CameraPreviewView({super.key});
|
const CameraPreviewView({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
State<CameraPreviewView> createState() => _CameraPreviewViewState();
|
||||||
return const MaterialApp(
|
|
||||||
title: 'Custom CamerAwesome UI',
|
|
||||||
home: CameraPage(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CameraPage extends StatelessWidget {
|
class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
const CameraPage({super.key});
|
double _lastZoom = 1;
|
||||||
|
double _basePanY = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Padding(
|
||||||
body: CameraAwesomeBuilder.awesome(
|
padding: EdgeInsets.only(top: 50, bottom: 30, left: 5, right: 5),
|
||||||
saveConfig: SaveConfig.photo(),
|
child: ClipRRect(
|
||||||
sensorConfig: SensorConfig.single(
|
borderRadius: BorderRadius.circular(22),
|
||||||
sensor: Sensor.position(SensorPosition.back),
|
child: CameraAwesomeBuilder.custom(
|
||||||
aspectRatio: CameraAspectRatios.ratio_1_1,
|
progressIndicator: Container(),
|
||||||
),
|
builder: (cameraState, preview) {
|
||||||
previewFit: CameraPreviewFit.contain,
|
return Container(
|
||||||
previewPadding: const EdgeInsets.only(left: 150, top: 100),
|
child: Stack(
|
||||||
previewAlignment: Alignment.topRight,
|
alignment: Alignment.bottomCenter,
|
||||||
// Buttons of CamerAwesome UI will use this theme
|
children: [
|
||||||
theme: AwesomeTheme(
|
Positioned.fill(
|
||||||
bottomActionsBackgroundColor: Colors.cyan.withAlpha(150),
|
child: GestureDetector(
|
||||||
buttonTheme: AwesomeButtonTheme(
|
onPanStart: (details) async {
|
||||||
backgroundColor: Colors.cyan.withAlpha(150),
|
setState(() {
|
||||||
iconSize: 20,
|
_basePanY = details.localPosition.dy;
|
||||||
foregroundColor: Colors.white,
|
});
|
||||||
padding: const EdgeInsets.all(16),
|
},
|
||||||
// Tap visual feedback (ripple, bounce...)
|
onPanUpdate: (details) async {
|
||||||
buttonBuilder: (child, onTap) {
|
var diff = _basePanY - details.localPosition.dy;
|
||||||
return ClipOval(
|
if (diff > 200) diff = 200;
|
||||||
child: Material(
|
if (diff < 0) diff = 0;
|
||||||
color: Colors.transparent,
|
var tmp = (diff / 200 * 50).toInt() / 50;
|
||||||
shape: const CircleBorder(),
|
if (tmp != _lastZoom) {
|
||||||
child: InkWell(
|
cameraState.sensorConfig.setZoom(tmp);
|
||||||
splashColor: Colors.cyan,
|
setState(() {
|
||||||
highlightColor: Colors.cyan.withAlpha(150),
|
_lastZoom = tmp;
|
||||||
onTap: onTap,
|
});
|
||||||
child: child,
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Positioned(
|
||||||
);
|
bottom: 30,
|
||||||
},
|
left: 0,
|
||||||
),
|
right: 0,
|
||||||
),
|
child: Align(
|
||||||
topActionsBuilder: (state) => AwesomeTopActions(
|
alignment: Alignment.bottomCenter,
|
||||||
padding: EdgeInsets.zero,
|
child: Column(
|
||||||
state: state,
|
children: [
|
||||||
children: [
|
AwesomeZoomSelector(state: cameraState
|
||||||
Expanded(
|
// controller: _controller,
|
||||||
child: AwesomeFilterWidget(
|
),
|
||||||
state: state,
|
const SizedBox(height: 30),
|
||||||
filterListPosition: FilterListPosition.aboveButton,
|
GestureDetector(
|
||||||
filterListPadding: const EdgeInsets.only(top: 8),
|
onTap: () async {
|
||||||
),
|
cameraState.when(
|
||||||
),
|
onPhotoMode: (picState) =>
|
||||||
],
|
picState.takePhoto());
|
||||||
),
|
// await takePicture();
|
||||||
middleContentBuilder: (state) {
|
},
|
||||||
return Column(
|
onLongPress: () async {},
|
||||||
children: [
|
child: Align(
|
||||||
const Spacer(),
|
alignment: Alignment.center,
|
||||||
Builder(builder: (context) {
|
child: Container(
|
||||||
return Container(
|
height: 100,
|
||||||
color: AwesomeThemeProvider.of(context)
|
width: 100,
|
||||||
.theme
|
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||||
.bottomActionsBackgroundColor,
|
padding: const EdgeInsets.all(2),
|
||||||
child: const Align(
|
decoration: BoxDecoration(
|
||||||
alignment: Alignment.bottomCenter,
|
shape: BoxShape.circle,
|
||||||
child: Padding(
|
border: Border.all(
|
||||||
padding: EdgeInsets.only(bottom: 10, top: 10),
|
width: 7,
|
||||||
child: Text(
|
color: Colors.white,
|
||||||
"Take your best shot!",
|
),
|
||||||
style: TextStyle(
|
),
|
||||||
color: Colors.white,
|
),
|
||||||
fontWeight: FontWeight.bold,
|
),
|
||||||
fontStyle: FontStyle.italic,
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
}),
|
),
|
||||||
],
|
);
|
||||||
);
|
},
|
||||||
},
|
saveConfig: SaveConfig.photoAndVideo(),
|
||||||
bottomActionsBuilder: (state) => AwesomeBottomActions(
|
previewPadding: const EdgeInsets.all(10),
|
||||||
state: state,
|
// onPreviewTapBuilder: (state) => OnPreviewTap(
|
||||||
left: AwesomeFlashButton(
|
// onTap: (Offset position, PreviewSize flutterPreviewSize,
|
||||||
state: state,
|
// PreviewSize pixelPreviewSize) {
|
||||||
),
|
// state.when(onPhotoMode: (picState) => picState.takePhoto());
|
||||||
right: AwesomeCameraSwitchButton(
|
// },
|
||||||
state: state,
|
// onTapPainter: (tapPosition) => TweenAnimationBuilder(
|
||||||
scale: 1.0,
|
// key: ValueKey(tapPosition),
|
||||||
onSwitchTap: (state) {
|
// tween: Tween<double>(begin: 1.0, end: 0.0),
|
||||||
state.switchCameraSensor(
|
// duration: const Duration(milliseconds: 500),
|
||||||
aspectRatio: state.sensorConfig.aspectRatio,
|
// 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<CameraZoomButtons> createState() => _CameraZoomButtonsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CameraZoomButtonsState extends State<CameraZoomButtons> {
|
||||||
|
@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("");
|
||||||
|
// }
|
||||||
|
// }),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue