no message

This commit is contained in:
1147192855@qq.com 2024-05-07 19:25:16 +08:00
parent 84f9d7a4ea
commit eb65701324
3 changed files with 208 additions and 160 deletions

View File

@ -46,7 +46,8 @@ import 'dart:ui' as ui;
import 'package:uuid/uuid.dart';
import 'package:zoom_widget/zoom_widget.dart';
// import 'package:zoom_widget/zoom_widget.dart';
import '../pages/marking/provider/draw_marking_provider.dart';
part 'PictureOverview.g.dart';
typedef PageChanged = void Function(int index);
@ -100,6 +101,10 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
late RemoveListener _annotationsListener; //
File? temFile; //
//
Offset? globalPosition; //
MarkingHistoryZoomInfo? zoomInfo;
@override
void initState() {
super.initState();
@ -108,7 +113,7 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
bool flag = value.questionNum == widget.questionNum && value.markingUserId == widget.markingUserId;
if (flag) {
if (value.positionX != 0 && value.positionY != 0) {
zoomOffset = Offset(value.positionX, value.positionY);
// zoomOffset = Offset(value.positionX, value.positionY);
}
if (value.scale < 1) {
initScale = value.scale;
@ -127,7 +132,6 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
@override
void dispose() {
super.dispose();
_annotationsListener();
try {
_imageStream?.removeListener(_imageStreamListener!);
@ -135,7 +139,9 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
bool flieExist = temFile!.existsSync();
if (flieExist) temFile!.delete();
}
if (zoomOffset != null) saveZoomPosition();
} catch (e) {}
super.dispose();
}
Future<FileResult?> saveImage() async {
@ -208,21 +214,51 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
FastData.getInstance().setMarkingZoomInfo(info);
}
void saveZoomPosition() async {
MarkingHistoryZoomInfo? historyZoomInfo = await FastData.getInstance().getMarkingZoomInfo();
if (historyZoomInfo != null) {
FastData.getInstance().setMarkingZoomInfo(MarkingHistoryZoomInfo(
scale: historyZoomInfo.scale,
positionX: zoomOffset!.dx,
positionY: zoomOffset!.dy,
questionNum: historyZoomInfo.questionNum,
markingUserId: historyZoomInfo.markingUserId,
));
}
}
void onPanUpPosition(Offset val) async {
print('**************** 正在移动位置 YYY:${val.dy}');
print('**************** 正在移动位置 XXX:${val.dx}');
zoomOffset = val;
}
// ==>
void onScaleUpdate(double scale, double scale1) async {
print('这是第一个scale$scale');
print('这是第二个noScale$scale1');
void onScaleUpdate(double scale, double zoom) async {
print('zoom$zoom');
print('scale${scale}');
// MarkingHistoryZoomInfo? historyZoomInfo = await FastData.getInstance().getMarkingZoomInfo();
MarkingHistoryZoomInfo? historyZoomInfo = await FastData.getInstance().getMarkingZoomInfo();
double positionX = historyZoomInfo?.positionX ?? 0;
double positionY = historyZoomInfo?.positionY ?? 0;
MarkingHistoryZoomInfo info = MarkingHistoryZoomInfo(
scale: scale1,
scale: zoom,
positionX: positionX,
positionY: positionY,
questionNum: widget.questionNum,
markingUserId: widget.markingUserId,
);
zoomInfo = info;
if (imagInfoModel != null) {
imagInfoModel = TestQuestionsImageInfo(
//
boxHeight: imagInfoModel!.boxHeight,
boxWidth: imagInfoModel!.boxWidth,
url: imagInfoModel!.url,
height: imagInfoModel!.height * zoom,
width: imagInfoModel!.width * zoom,
);
}
FastData.getInstance().setMarkingZoomInfo(info);
}
@ -237,6 +273,7 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
double containerWidth = constraints.maxWidth;
double containerHeight = constraints.maxHeight;
print('LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL');
return $LocalAndNetworkSwitch(
zoomGlobalKey: zoomGlobalKey,
containerWidth: containerWidth,
@ -254,7 +291,8 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
temFile = file;
print('更新需要上传的文件');
},
imageBuilder: (context, imageProvider) {
imageBuilder: (imageBuilderContext, imageProvider) {
print('PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP');
Image imageWidget = Image(image: imageProvider, fit: BoxFit.fitWidth);
if (imagInfoModel == null || (imagInfoModel?.boxHeight != containerHeight || imagInfoModel?.boxWidth != containerWidth)) {
if (_imageStreamListener != null) _imageStream?.removeListener(_imageStreamListener!);
@ -276,19 +314,83 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
}
// return imageWidget;
return Zoom(
// initTotalZoomOut: true,
child: imageWidget,
maxZoomWidth: containerWidth,
canvasColor: Colors.transparent,
backgroundColor: Colors.transparent,
maxZoomHeight: imagInfoModel?.scaleHeight,
initScale: initScale ?? 1,
initPosition: zoomOffset,
// initPosition: ,
// onPositionUpdate: onPositionUpdate,
onScaleUpdate: onScaleUpdate,
// zoomSensibility: 0.5,
return Listener(
behavior: HitTestBehavior.opaque,
onPointerMove: (PointerMoveEvent details) {
return;
if (globalPosition != null) {
//
double dx = globalPosition!.dx;
double dy = globalPosition!.dy;
double dxNew = details.localPosition.dx;
double dyNew = details.localPosition.dy;
if ((dxNew - dx).abs() > 22 || (dyNew - dy).abs() > 22) return;
}
globalPosition = details.localPosition;
// Offset localPosition = (context.findRenderObject() as RenderBox).globalToLocal(details.localPosition);
// if (widget.graffitiSwitch.openBrush || widget.graffitiSwitch.openEraser) {
Offset localPosition = globalPosition!;
// if (imagInfoModel?.scaleHeight != null) {
// localPosition = Offset(localPosition.dx, localPosition.dy - imagInfoModel!.scaleHeight!);
// }
double remainingHeight = imagInfoModel!.imageHeightOffsetStart!; //
var _scaleY = (zoomInfo?.scale ?? 1);
if (remainingHeight > 1) {
localPosition = Offset(localPosition.dx, localPosition.dy - remainingHeight);
}
if (zoomOffset != null) {
// localPosition = Offset(localPosition.dx - (zoomOffset?.dx ?? 0), localPosition.dy);
}
print('移动位置 zoomOffset==>dx${zoomOffset?.dx}');
print('移动位置 zoomOffset==>dy${zoomOffset?.dy}');
print('缩放的比例:${_scaleY}');
print('原本的dy${globalPosition?.dy}');
print('原本的dx${globalPosition?.dx}');
print('本来的Y轴${localPosition.dy}');
print('还原后的Y轴${localPosition.dy * _scaleY}');
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser, data: localPosition));
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal));
},
onPointerDown: (PointerDownEvent event) {
print('手指按下....${event.pointer}');
},
onPointerUp: (PointerUpEvent details) {
print('离开.............');
return;
globalPosition = null;
// if (graffitiSwitch.openBrush || graffitiSwitch.openEraser) {
// var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
// ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal));
// }
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal));
},
child: Zoom(
// initTotalZoomOut: true,
child: ExamPaperDrawing(
key: examPaperDrawingKey,
globalKey: theglobalKey,
child: imageWidget,
graffitiSwitch: graffitiSwitch,
decoration: const BoxDecoration(color: const Color.fromRGBO(249, 250, 254, 1)),
),
maxZoomWidth: containerWidth,
canvasColor: Colors.transparent,
backgroundColor: Colors.transparent,
maxZoomHeight: imagInfoModel?.scaleHeight,
initScale: initScale ?? 1,
initPosition: zoomOffset,
onScaleUpdate: onScaleUpdate,
onPositionUpdate: onPanUpPosition,
),
);
},
);
@ -300,24 +402,16 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
//
class ExamPaperDrawing extends StatefulHookConsumerWidget {
// String imgUrl;
bool homework;
Widget child;
BoxDecoration? decoration;
AnnotationGraffitiSwitch graffitiSwitch;
List<GestureRecording>? points;
List<dynamic>? pointsPureData;
ValueNotifier<Map<String, ui.Image>> imageLoaded;
Widget child;
GlobalKey globalKey;
// Function(String) imageCall;
ExamPaperDrawing({
// required this.imgUrl,
required this.homework,
required this.points,
required this.pointsPureData,
required this.child,
required this.graffitiSwitch,
required this.globalKey,
required this.imageLoaded,
required this.child,
this.decoration,
Key? key,
}) : super(key: key);
@ -328,19 +422,19 @@ class ExamPaperDrawing extends StatefulHookConsumerWidget {
class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventBusMixin<BottomAnnotationSwitchCleanall> {
//
late List<GestureRecording> points;
late List<dynamic> pointsPureData;
//
Offset? globalPosition; //
late RemoveListener removeListener;
late ValueNotifier<List<GestureRecording>> _vnHandWritings;
late List<dynamic> pointsPureData = [];
@override
void initState() {
points = widget.points ?? [];
pointsPureData = widget.pointsPureData ?? [];
_vnHandWritings = ValueNotifier<List<GestureRecording>>([]);
removeListener = ref.read(drawMarkingProvider.notifier).addListener((state) => _vnHandWritings.value = [...state.data], fireImmediately: false);
// 线
eventOn(callback: (BottomAnnotationSwitchCleanall item) {
if (item.previousStep) {
if (points.isEmpty) {
if (_vnHandWritings.value.isEmpty) {
ToastUtils.showInfo('批注已清空');
return;
}
@ -348,14 +442,15 @@ class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventB
if (index != -1) {
if (index + 1 == pointsPureData.length) {
pointsPureData = pointsPureData.sublist(0, index);
points.sublist(0, index);
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(ref.read(drawMarkingProvider).data.sublist(0, index)));
index = pointsPureData.toList().lastIndexOf(null);
index == -1 ? -1 : index + 1;
}
if (index != -1) {
pointsPureData = pointsPureData.sublist(0, index);
points = points.sublist(0, index);
toUpState(setState, () {}, mounted);
_vnHandWritings.value = _vnHandWritings.value.sublist(0, index);
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(ref.read(drawMarkingProvider).data.sublist(0, index)));
} else {
item.cleanAll = true;
}
@ -366,8 +461,7 @@ class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventB
if (item.cleanAll) {
pointsPureData.clear();
points.clear();
toUpState(setState, () {}, mounted);
_vnHandWritings.value.clear();
}
if (item.uploadImage) {
@ -388,75 +482,47 @@ class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventB
@override
void dispose() {
super.dispose();
eventCancel();
removeListener();
_vnHandWritings.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Listener(
behavior: HitTestBehavior.opaque,
onPointerMove: (PointerMoveEvent details) {
if (globalPosition != null) {
//
double dx = globalPosition!.dx;
double dy = globalPosition!.dy;
print('_ExamPaperDrawingState的build....');
double dxNew = details.localPosition.dx;
double dyNew = details.localPosition.dy;
if ((dxNew - dx).abs() > 22 || (dyNew - dy).abs() > 22) {
return;
}
}
globalPosition = details.localPosition;
try {
// if (widget.graffitiSwitch.openBrush || widget.graffitiSwitch.openEraser) {
RenderBox renderBox = context.findRenderObject() as RenderBox;
Offset localPosition = renderBox.globalToLocal(details.localPosition);
pointsPureData = List.from(pointsPureData)..add(localPosition);
points = List.from(points)..add(GestureRecording(eraser: widget.graffitiSwitch.openEraser, data: localPosition));
setState(() {});
// }
} catch (e) {
toPrint(val: '进入报错');
}
},
onPointerUp: (PointerUpEvent details) {
print('离开.............');
globalPosition = null;
if (widget.graffitiSwitch.openBrush || widget.graffitiSwitch.openEraser) {
pointsPureData.add(null); // 线
points.add(GestureRecording(eraser: widget.graffitiSwitch.openEraser));
}
},
child: RepaintBoundary(
key: widget.globalKey,
child: CustomPaint(
foregroundPainter: DrawingPainter(points: points),
child: widget.child,
),
return RepaintBoundary(
key: widget.globalKey,
child: CustomPaint(
isComplex: true,
willChange: true,
foregroundPainter: DrawingPainter(ctrl: _vnHandWritings),
child: RepaintBoundary(child: widget.child),
),
);
}
}
class DrawingPainter extends CustomPainter {
final List<GestureRecording> points;
DrawingPainter({required this.points}) : super();
final Paint paintBrush = Paint()
..color = Colors.red
..strokeCap = StrokeCap.round
..strokeWidth = 1.5.r;
final ValueNotifier<List<GestureRecording>> ctrl;
final Paint paintBrush = Paint();
DrawingPainter({required this.ctrl}) : super(repaint: ctrl) {
paintBrush
..color = Colors.red
..strokeCap = StrokeCap.round
..strokeWidth = 1.5.r;
}
@override
void paint(Canvas canvas, Size size) {
print('数据.....................');
for (int i = 0; i < points.length; i++) {
var points = ctrl.value;
var pointsLength = points.length;
print('数据.....................[[[[[${points.length}]]]]]');
for (int i = 0; i < pointsLength; i++) {
GestureRecording item = points[i];
GestureRecording nextItem = points[i + 1];
Offset? offsetData = item.data;
Offset? nextOffsetData = nextItem.data;
Offset? nextOffsetData = pointsLength - 1 == i ? null : points[i + 1].data;
if (offsetData != null && nextOffsetData != null) {
canvas.drawLine(offsetData, nextOffsetData, paintBrush);
}
@ -464,8 +530,16 @@ class DrawingPainter extends CustomPainter {
}
@override
bool shouldRepaint(DrawingPainter oldDelegate) {
return oldDelegate.points.length != points.length || oldDelegate.points != points;
bool shouldRepaint(covariant CustomPainter oldDelegate) {
print('FFFFFF55555555555555');
// if (oldDelegate is DrawingPainter) {
// var repaint = ctrl.value.length != oldDelegate.ctrl.value.length || oldDelegate.ctrl.value != ctrl.value;
// print('调用是否绘制:$repaint');
// return repaint;
// }
return false;
}
}
@ -525,51 +599,6 @@ Widget $myCachedNetworkImage({
);
},
);
// return Container(
// width: width,
// height: height,
// color: Colors.red,
// alignment: Alignment.center,
// child: tempFile != null
// ? Image.file(
// tempFile,
// fit: BoxFit.contain,
// width: double.infinity,
// height: double.infinity,
// )
// : CachedNetworkImage(
// key: _useImgRefsh.imageKey.value,
// fit: BoxFit.contain,
// width: double.infinity,
// // height: double.infinity,
// imageUrl: imageUrl,
// placeholder: (context, url) =>
// Center(child: SpinKitWave(color: Theme.of(context).primaryColor, size: 50.r)),
// // imageBuilder: (context, imageProvider) => Container(
// // decoration: BoxDecoration(
// // image: DecorationImage(
// // image: imageProvider,
// // fit: BoxFit.fitWidth,
// // // colorFilter: ColorFilter.mode(Colors.red, BlendMode.colorBurn),
// // ),
// // ),
// // ),
// errorWidget: (context, url, error) {
// return GestureDetector(
// onTap: () => (_useImgRefsh.imageKey.value = UniqueKey()),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Image.asset('assets/images/test_paper_loading_failed.png'),
// quickText('加载失败,点击重试', color: Color.fromRGBO(148, 163, 182, 1), size: 12.sp),
// ],
// ),
// );
// },
// ),
// );
}
class CacheNetImageView extends ConsumerWidget {
@ -679,22 +708,12 @@ Widget $localAndNetworkSwitch(
}, []);
print('是否更新视图.... ${_useZoomHistory.initPosition.value}');
return ExamPaperDrawing(
graffitiSwitch: graffitiSwitch,
points: _useSwitch.points.value,
pointsPureData: _useSwitch.pointsPureData.value,
decoration: const BoxDecoration(color: const Color.fromRGBO(249, 250, 254, 1)),
globalKey: theglobalKey,
key: examGlobalKey,
imageLoaded: _useSwitch.imageLoaded,
homework: homework,
child: $MyCachedNetworkImage(
imageUrl: imageUrl,
tempFile: _useSwitch.temFile.value,
width: containerWidth,
height: containerHeight,
imageBuilder: imageBuilder,
),
return $MyCachedNetworkImage(
imageUrl: imageUrl,
tempFile: _useSwitch.temFile.value,
width: containerWidth,
height: containerHeight,
imageBuilder: imageBuilder,
);
}
@ -758,7 +777,7 @@ class UseLocalAndNetworkSwitch {
temFile.value?.delete();
temFile.value = file; //
points.value = examGlobalKey.currentState?.points;
points.value = examGlobalKey.currentState?._vnHandWritings.value;
pointsPureData.value = examGlobalKey.currentState?.pointsPureData;
toPrint(val: '图片保存成功:');
return temFile.value;

View File

@ -1916,7 +1916,7 @@ class _MarkingPapersState extends ConsumerState<DoPapers>
children: [
//
Container(
margin: EdgeInsets.only(top: 6.h),
// margin: EdgeInsets.only(top: 6.h),
padding: EdgeInsets.symmetric(horizontal: 1.w),
child: PictureOverview(
questionNum: data.questionNum,

View File

@ -0,0 +1,29 @@
/*
* @Author: wangyang 1147192855@qq.com
* @Date: 2022-07-14 18:16:06
* @LastEditors: wangyang 1147192855@qq.com
* @LastEditTime: 2022-08-01 16:17:33
* @FilePath: \marking_app\lib\provider\user_provider.dart
* @Description: APP上传文件状态
*/
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../../components/PictureOverview.dart';
//
final drawMarkingProvider = StateNotifierProvider<DrawMarkingProviderHandle, DrawMarkingVal>((ref) => DrawMarkingProviderHandle(DrawMarkingVal([])));
class DrawMarkingProviderHandle extends StateNotifier<DrawMarkingVal> {
DrawMarkingProviderHandle(DrawMarkingVal val) : super(val);
void setState(DrawMarkingVal val) {
state = val;
}
}
class DrawMarkingVal {
List<GestureRecording> data;
DrawMarkingVal(this.data);
}