diff --git a/marking_app/README.md b/marking_app/README.md
index 0b70d96..7622a87 100644
--- a/marking_app/README.md
+++ b/marking_app/README.md
@@ -14,3 +14,7 @@ A few resources to get you started if this is your first Flutter project:
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
+
+
+
+fvm flutter build apk --release --no-tree-shake-icons
\ No newline at end of file
diff --git a/marking_app/android/app/src/main/AndroidManifest.xml b/marking_app/android/app/src/main/AndroidManifest.xml
index 8348071..df14510 100644
--- a/marking_app/android/app/src/main/AndroidManifest.xml
+++ b/marking_app/android/app/src/main/AndroidManifest.xml
@@ -35,7 +35,14 @@
android:name="flutterEmbedding"
android:value="2" />
-
+
+
+
+
@@ -47,8 +54,10 @@
-
-
+
+
+
+
@@ -58,4 +67,6 @@
+
+
diff --git a/marking_app/android/app/src/main/res/xml/file_paths.xml b/marking_app/android/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 0000000..c4e8da4
--- /dev/null
+++ b/marking_app/android/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/marking_app/android/app/src/profile/AndroidManifest.xml b/marking_app/android/app/src/profile/AndroidManifest.xml
index 6281e88..186b8b4 100644
--- a/marking_app/android/app/src/profile/AndroidManifest.xml
+++ b/marking_app/android/app/src/profile/AndroidManifest.xml
@@ -13,9 +13,13 @@
-
+
-
+
+
+
+
+
diff --git a/marking_app/lib/common/model/enum/review_marks_bottom_btns_enum.dart b/marking_app/lib/common/model/enum/review_marks_bottom_btns_enum.dart
new file mode 100644
index 0000000..5698a07
--- /dev/null
+++ b/marking_app/lib/common/model/enum/review_marks_bottom_btns_enum.dart
@@ -0,0 +1,6 @@
+enum ReviewMarksBottomBtnsEnum {
+ DRAG, // 拖动
+ HANDWRITING, // 笔迹
+ RETURN_PREVIOUS_LEVEL, // 返回上一级
+ CLEAR_ALL // 清空全部
+}
diff --git a/marking_app/lib/common/model/event_bus/bottom_annotation_switch_cleanall.dart b/marking_app/lib/common/model/event_bus/bottom_annotation_switch_cleanall.dart
index 89e53ca..fec4a61 100644
--- a/marking_app/lib/common/model/event_bus/bottom_annotation_switch_cleanall.dart
+++ b/marking_app/lib/common/model/event_bus/bottom_annotation_switch_cleanall.dart
@@ -15,8 +15,23 @@ class BottomAnnotationSwitchCleanall extends Object {
BottomAnnotationSwitchCleanall({this.cleanAll = false, this.previousStep = false, this.uploadImage = false});
- factory BottomAnnotationSwitchCleanall.fromJson(Map srcJson) =>
- _$BottomAnnotationSwitchCleanallFromJson(srcJson);
+ factory BottomAnnotationSwitchCleanall.fromJson(Map srcJson) => _$BottomAnnotationSwitchCleanallFromJson(srcJson);
Map toJson() => _$BottomAnnotationSwitchCleanallToJson(this);
}
+
+@JsonSerializable()
+class BottomAnnotationSwitchCleanallOfMarking extends Object {
+ @JsonKey(name: 'cleanAll')
+ bool cleanAll;
+
+ @JsonKey(name: 'previousStep')
+ bool previousStep;
+
+ BottomAnnotationSwitchCleanallOfMarking({this.cleanAll = false, this.previousStep = false});
+
+ factory BottomAnnotationSwitchCleanallOfMarking.fromJson(Map srcJson) =>
+ _$BottomAnnotationSwitchCleanallOfMarkingFromJson(srcJson);
+
+ Map toJson() => _$BottomAnnotationSwitchCleanallOfMarkingToJson(this);
+}
diff --git a/marking_app/lib/common/model/job/gesture_recording.dart b/marking_app/lib/common/model/job/gesture_recording.dart
index 5e36be8..f021a6e 100644
--- a/marking_app/lib/common/model/job/gesture_recording.dart
+++ b/marking_app/lib/common/model/job/gesture_recording.dart
@@ -41,3 +41,11 @@ class GestureHandwritingRecording {
required this.intervalTime,
});
}
+
+/**
+ * 笔记还原页面 查看原稿
+ */
+class ShowStudentMmanuscript {
+ bool showManuscript; // 查看原稿
+ ShowStudentMmanuscript(this.showManuscript);
+}
diff --git a/marking_app/lib/common/model/job/test_questions_image_info.dart b/marking_app/lib/common/model/job/test_questions_image_info.dart
index e9a1e7c..23539ea 100644
--- a/marking_app/lib/common/model/job/test_questions_image_info.dart
+++ b/marking_app/lib/common/model/job/test_questions_image_info.dart
@@ -35,8 +35,17 @@ class TestQuestionsImageInfo extends Object {
double? imageHeightOffsetend;
- TestQuestionsImageInfo(
- {required this.width, required this.height, required this.url, required this.boxWidth, required this.boxHeight, this.pixelRatio = 1}) {
+ double zoom; // 图片放大比例
+
+ TestQuestionsImageInfo({
+ required this.width,
+ required this.height,
+ required this.url,
+ required this.boxWidth,
+ required this.boxHeight,
+ this.pixelRatio = 1,
+ this.zoom = 1,
+ }) {
// print('图片宽度:$width');
// print('图片高度:$height');
@@ -46,11 +55,11 @@ class TestQuestionsImageInfo extends Object {
pixelRatio = width / boxWidth;
scale = boxWidth / width;
- scaleHeight = scale! * height;
- scaleWidth = scale! * width;
+ scaleHeight = scale! * height * zoom;
+ scaleWidth = scale! * width * zoom;
if (scaleHeight != null) {
- imageHeightOffsetStart = (boxHeight - scaleHeight!) / 2;
+ imageHeightOffsetStart = boxHeight <= scaleHeight! ? 0 : (boxHeight - scaleHeight!) / 2;
imageHeightOffsetend = imageHeightOffsetStart! + scaleHeight!;
}
}
diff --git a/marking_app/lib/common/model/marking/marking_text_question.dart b/marking_app/lib/common/model/marking/marking_text_question.dart
index f206ab9..d917720 100644
--- a/marking_app/lib/common/model/marking/marking_text_question.dart
+++ b/marking_app/lib/common/model/marking/marking_text_question.dart
@@ -96,9 +96,9 @@ class MarkingTextQuestion extends Object {
@JsonKey(name: 'papersUrlStr')
List? papersUrlStr;
- // 批注图片 预提交集合
- @JsonKey(name: 'commentImageUrlTodo')
- List? commentImageUrlTodo;
+ // // 批注图片 预提交集合
+ // @JsonKey(name: 'commentImageUrlTodo')
+ // List? commentImageUrlTodo;
// 批注图片Map
@JsonKey(name: 'commentImageUrlMap')
@@ -115,8 +115,8 @@ class MarkingTextQuestion extends Object {
@JsonKey(name: 'historicalScorings')
List? historicalScorings;
- MarkingTextQuestion(this.id, this.totalScore, this.isFinish, this.subQuestionDetailList, this.isException,
- this.questionNum, this.score, this.studentAnswerList,
+ MarkingTextQuestion(
+ this.id, this.totalScore, this.isFinish, this.subQuestionDetailList, this.isException, this.questionNum, this.score, this.studentAnswerList,
// this.questionIndex,
{required this.commentImageUrl,
required this.lastOne,
@@ -130,7 +130,7 @@ class MarkingTextQuestion extends Object {
// this.totalCount = 0,
// this.currentIndex = 0,
this.papersUrl = const [],
- this.commentImageUrlTodo,
+ // this.commentImageUrlTodo,
this.commentImageUrlMap = const {}}) {
score = isFinish ? score : null;
completeRating = isFinish && score != null;
@@ -140,14 +140,20 @@ class MarkingTextQuestion extends Object {
commentImageUrlMap = Map();
if (commentImageUrl.isNotEmpty) {
- for (var element in commentImageUrl) {
- commentImageUrlMap[element] = '$element?${DateTime.now().millisecondsSinceEpoch}';
+ // for (var element in commentImageUrl) {
+ // commentImageUrlMap[element] = '$element?${DateTime.now().millisecondsSinceEpoch}';
+ // }
+ for (var i = 0; i < commentImageUrl.length; i++) {
+ var element = commentImageUrl[i];
+ var originalImage = studentAnswerList[i];
+ commentImageUrlMap[originalImage] = 'https:$element?${DateTime.now().millisecondsSinceEpoch}';
}
} else {
for (var element in studentAnswerList) {
commentImageUrlMap[element] = element;
}
}
+
// if (historicalScore != null) {
// this.historicalScorings = (jsonDecode(historicalScore!) as List).map((e) {
// return HistoricalScoring.fromJson(e as Map);
@@ -165,10 +171,6 @@ class MarkingTextQuestion extends Object {
factory MarkingTextQuestion.fromJson(Map srcJson) => _$MarkingTextQuestionFromJson(srcJson);
List getImageData() {
- if (commentImageUrlTodo != null && commentImageUrlTodo!.isNotEmpty) {
- return commentImageUrlTodo!;
- }
-
if (commentImageUrl.isNotEmpty) {
return commentImageUrl;
}
@@ -178,10 +180,8 @@ class MarkingTextQuestion extends Object {
bool setImageList(String resImage, int imageIndex) {
try {
- commentImageUrlTodo ??= getImageData().map((e) => e).toList();
String oldImage = studentAnswerList[imageIndex];
commentImageUrlMap[oldImage] = '$resImage?${DateTime.now().millisecondsSinceEpoch}';
- commentImageUrlTodo![imageIndex] = resImage;
return true;
} catch (e) {
return false;
@@ -220,11 +220,7 @@ class SubQuestions extends Object {
bool completeRating;
SubQuestions(
- {required this.subQuestionScore,
- required this.subQuestionNum,
- this.subQuestionGotScore,
- required this.isFinish,
- this.completeRating = false}) {
+ {required this.subQuestionScore, required this.subQuestionNum, this.subQuestionGotScore, required this.isFinish, this.completeRating = false}) {
subQuestionGotScore = isFinish ? subQuestionGotScore : null;
completeRating = isFinish && subQuestionGotScore != null;
}
diff --git a/marking_app/lib/components/PictureOverview.dart b/marking_app/lib/components/PictureOverview.dart
index 545f4c5..d9e4fb4 100644
--- a/marking_app/lib/components/PictureOverview.dart
+++ b/marking_app/lib/components/PictureOverview.dart
@@ -22,6 +22,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/common/model/common/upload_img_secret_key.dart';
+import 'package:marking_app/common/model/enum/review_marks_bottom_btns_enum.dart';
import 'package:marking_app/common/model/event_bus/bottom_annotation_switch_cleanall.dart';
import 'package:marking_app/common/model/job/test_questions_image_info.dart';
import 'package:marking_app/common/model/job/upload_file_interface_config.dart';
@@ -29,10 +30,12 @@ import 'package:marking_app/common/model/job/upload_file_interface_config_params
import 'package:marking_app/common/model/marking/annotation_graffiti_switch.dart';
import 'package:marking_app/common/model/marking/do_marking_keyboard_model.dart';
import 'package:marking_app/common/model/marking/marking_history_zoom_info.dart';
+import 'package:marking_app/common/model/marking/marking_text_question.dart';
import 'package:marking_app/common/model/marking/switch_keyboard_to_reload_images.dart';
import 'package:marking_app/pages/common/event_bus_mixin.dart';
import 'package:marking_app/pages/homework_correction/hooks/use_cached_img_refresh.dart';
import 'package:marking_app/pages/marking/hooks/use_zoom_image_history.dart';
+import 'package:marking_app/pages/marking/provider/do_paper_bottom_review_marks_provider.dart';
import 'package:marking_app/pages/marking/provider/zoom_height_provider.dart';
import 'package:marking_app/pages/marking/provider/zoom_history_provider.dart';
import 'package:marking_app/provider/annotation_graffiti_switch_provider.dart';
@@ -46,7 +49,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);
@@ -66,6 +70,8 @@ class PictureOverview extends StatefulHookConsumerWidget {
final bool annotationsFlag;
final String testQuestionNumber;
final Map commentImageMap;
+ final MarkingTextQuestion data;
+ final Function callAnnotationTips;
const PictureOverview({
required this.imageItems,
@@ -74,6 +80,8 @@ class PictureOverview extends StatefulHookConsumerWidget {
required this.testQuestionNumber,
required this.questionNum,
required this.markingUserId,
+ required this.data,
+ required this.callAnnotationTips,
this.homework = false,
this.imageScale = 1,
this.imagePosition,
@@ -84,7 +92,7 @@ class PictureOverview extends StatefulHookConsumerWidget {
PictureOverviewState createState() => PictureOverviewState();
}
-class PictureOverviewState extends ConsumerState with CommonMixin {
+class PictureOverviewState extends ConsumerState with CommonMixin, EventBusMixin {
final GlobalKey theglobalKey = GlobalKey();
final GlobalKey<_ExamPaperDrawingState> examPaperDrawingKey = GlobalKey<_ExamPaperDrawingState>();
final GlobalKey zoomGlobalKey = GlobalKey(); // zoom
@@ -100,6 +108,12 @@ class PictureOverviewState extends ConsumerState with CommonMix
late RemoveListener _annotationsListener; // 批注关闭监听
File? temFile; // 批注临时数据
+ // 用于记录绘图结果的变量
+ Offset? globalPosition; // 是否正在绘制
+ MarkingHistoryZoomInfo? zoomInfo;
+ bool illegalArea = false; // 非法区域(批阅笔迹不在试题图片中)
+ final GlobalKey _zoomKey = GlobalKey>();
+
@override
void initState() {
super.initState();
@@ -108,11 +122,12 @@ class PictureOverviewState extends ConsumerState 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;
- Future.delayed(Duration(seconds: 5), () => ref.read(zoomHistoryProvider.notifier).setState(initScale!));
+ // 5
+ Future.delayed(Duration(seconds: 1), () => ref.read(zoomHistoryProvider.notifier).setState(initScale!));
}
}
});
@@ -123,19 +138,49 @@ class PictureOverviewState extends ConsumerState with CommonMix
graffitiSwitch = state;
toUpState(setState, () {}, mounted);
});
+
+ // 事件总线监听 清空数据
+ eventOn(callback: (BottomAnnotationSwitchCleanallOfMarking item) async {
+ widget.callAnnotationTips(); // 调用回调 通知父级批注记录被更改
+ if (ref.read(drawMarkingProvider).data.isEmpty) {
+ if (widget.data.commentImageUrl.isNotEmpty) {
+ bool? res = await showDialog(
+ // 表示点击灰色背景的时候是否消失弹出框
+ barrierDismissible: false,
+ context: context,
+ builder: (context1) {
+ return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹"), actions: [
+ TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)),
+ TextButton(child: quickText("确定", color: Theme.of(context).primaryColor), onPressed: () => Navigator.pop(context1, true))
+ ]);
+ },
+ );
+ if (res == true) {
+ widget.data.commentImageUrl.removeAt(currentIndex);
+ var theUrl = widget.imageItems[currentIndex];
+ widget.commentImageMap[theUrl] = theUrl;
+ toUpState(setState, () {}, mounted);
+ }
+ } else {
+ ToastUtils.showInfo('批注已清空');
+ }
+ }
+ });
}
@override
void dispose() {
- super.dispose();
_annotationsListener();
+ eventCancel();
try {
_imageStream?.removeListener(_imageStreamListener!);
if (temFile != null) {
bool flieExist = temFile!.existsSync();
if (flieExist) temFile!.delete();
}
+ // if (zoomOffset != null) saveZoomPosition();
} catch (e) {}
+ super.dispose();
}
Future saveImage() async {
@@ -146,9 +191,12 @@ class PictureOverviewState extends ConsumerState with CommonMix
// 没有图片就上传图片
RenderRepaintBoundary? boundary = theglobalKey.currentContext!.findRenderObject() as RenderRepaintBoundary?;
if (boundary == null) return null;
- double dpr = MediaQuery.of(context).devicePixelRatio;
- // double dpr = ui.window.devicePixelRatio;
- ui.Image image = await boundary.toImage(pixelRatio: dpr);
+ // double dpr = MediaQuery.of(context).devicePixelRatio;
+
+ double pixelRatio = MediaQuery.of(context).devicePixelRatio;
+ if (imagInfoModel?.pixelRatio != null) pixelRatio = imagInfoModel!.pixelRatio;
+
+ ui.Image image = await boundary.toImage(pixelRatio: pixelRatio);
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
if (byteData == null) {
/// 等于null 已经是异常了
@@ -162,11 +210,14 @@ class PictureOverviewState extends ConsumerState with CommonMix
temFile = file;
}
- crypto.Digest fileMd5 = crypto.md5.convert(await temFile!.readAsBytes());
+ if (imagInfoModel != null) {
+ // 剪切图片
+ }
+ crypto.Digest fileMd5 = crypto.md5.convert(await temFile!.readAsBytes());
RestClient _client = await getClient();
- BaseStructureResult resUploadConfig =
- await _client.getUploadFile(UploadFileInterfaceConfigParams(
+
+ BaseStructureResult resUploadConfig = await _client.getMarkingUploadFile(UploadFileInterfaceConfigParams(
fileName: '1.png',
fileMd5: fileMd5.toString(),
contentLength: temFile!.lengthSync(),
@@ -179,8 +230,7 @@ class PictureOverviewState extends ConsumerState with CommonMix
if (resUploadConfig.data!.uploadUri == null) {
return FileResult(myObject: '', success: true, url: resUploadConfig.data!.downloadUri);
}
- FileResult? resFile =
- await ref.read(uploadFileProvider.notifier).getUploadFileConfig(resUploadConfig.data!, temFile!);
+ FileResult? resFile = await ref.read(uploadFileProvider.notifier).getUploadFileConfig(resUploadConfig.data!, temFile!);
// FileResult? resFile = await ref
// .read(uploadFileProvider.notifier)
// .uploadFile(temFile!.path, widget.imageItems[currentIndex], ref.read(userProvider).id.toString());
@@ -210,27 +260,60 @@ class PictureOverviewState extends ConsumerState 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 (double.parse(zoom.toStringAsFixed(2)) <= 1) zoom = 1;
+ if (imagInfoModel != null) {
+ // 根据缩放比例重置被放大的图片的尺寸
+ imagInfoModel = TestQuestionsImageInfo(
+ // 获取图片的宽高
+ boxHeight: imagInfoModel!.boxHeight,
+ boxWidth: imagInfoModel!.boxWidth,
+ url: imagInfoModel!.url,
+ height: imagInfoModel!.height,
+ width: imagInfoModel!.width,
+ zoom: zoom,
+ );
+ }
FastData.getInstance().setMarkingZoomInfo(info);
}
@override
Widget build(BuildContext context) {
- DoMarkingKeyboardModel _model = ref.watch(markingKeyboardProvider);
return Container(
width: double.infinity,
height: double.infinity,
@@ -257,10 +340,9 @@ class PictureOverviewState extends ConsumerState with CommonMix
temFile = file;
print('更新需要上传的文件');
},
- imageBuilder: (context, imageProvider) {
+ imageBuilder: (imageBuilderContext, imageProvider) {
Image imageWidget = Image(image: imageProvider, fit: BoxFit.fitWidth);
- if (imagInfoModel == null ||
- (imagInfoModel?.boxHeight != containerHeight || imagInfoModel?.boxWidth != containerWidth)) {
+ if (imagInfoModel == null || (imagInfoModel?.boxHeight != containerHeight || imagInfoModel?.boxWidth != containerWidth)) {
if (_imageStreamListener != null) _imageStream?.removeListener(_imageStreamListener!);
_imageStreamListener = ImageStreamListener((ImageInfo info, bool _) {
imagInfoModel = TestQuestionsImageInfo(
@@ -271,7 +353,6 @@ class PictureOverviewState extends ConsumerState with CommonMix
height: info.image.height.toDouble(),
width: info.image.width.toDouble(),
);
- printJson(imagInfoModel!.toJson());
Future.delayed(Duration.zero, () {
ref.read(zoomHeightProvider.notifier).setState(imagInfoModel?.scaleHeight ?? 0.0);
});
@@ -279,20 +360,111 @@ class PictureOverviewState extends ConsumerState with CommonMix
_imageStream = imageWidget.image.resolve(ImageConfiguration())..addListener(_imageStreamListener!);
}
+ var btnEnum = ref.watch(doPaperBottomReviewMarksProvider);
// 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) {
+ if (btnEnum != ReviewMarksBottomBtnsEnum.HANDWRITING) 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 = globalPosition!;
+
+ // if (imagInfoModel != null &&
+ // (localPosition.dy < imagInfoModel!.imageHeightOffsetStart! || localPosition.dy > imagInfoModel!.imageHeightOffsetend!)) {
+ // // 笔迹画出图片区域 直接断笔
+ // var dataVal = ref.read(drawMarkingProvider).data;
+ // if (dataVal.length - 1 > -1 && dataVal[dataVal.length - 1].data != null) {
+ // var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
+ // var newVal1 = ref.read(drawMarkingProvider).offsets..add(null);
+ // ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal, newVal1));
+ // }
+ // illegalArea = true;
+ // return;
+ // }
+ // illegalArea = false;
+
+ var _theKey = _zoomKey.currentState;
+ print(_theKey);
+
+ double remainingHeight = imagInfoModel!.imageHeightOffsetStart!; // 剩余高度
+ if (remainingHeight > 1) {
+ localPosition = Offset(localPosition.dx, localPosition.dy - remainingHeight);
+ }
+
+ // print(localPosition.dy);
+ print(localPosition.dx);
+
+ double _theZoomVal = imagInfoModel?.zoom ?? 1;
+ var _dx = zoomOffset?.dx ?? 0;
+ _dx = _dx > 0 ? 0 : _dx.abs() / _theZoomVal;
+ var _dy = zoomOffset?.dy ?? 0;
+ _dy = _dy > 0 ? 0 : _dy.abs() / _theZoomVal;
+
+ if (_theZoomVal > 1) {
+ // 计算视图被放大比例 还原笔迹坐标
+ localPosition = Offset(localPosition.dx / _theZoomVal, localPosition.dy / _theZoomVal);
+ if (zoomOffset != null) {
+ // 如果滚动条有触动就加上滚动条滚动的位置
+ localPosition = Offset(localPosition.dx + _dx, localPosition.dy + _dy);
+ }
+ } else if (_theZoomVal < 1) {
+ // 试图被缩小
+ double imgSpaceWidthOfSingle = (imagInfoModel!.boxWidth - imagInfoModel!.scaleWidth!) / 2;
+ localPosition = Offset((localPosition.dx - imgSpaceWidthOfSingle) / _theZoomVal, localPosition.dy / _theZoomVal + _dy);
+ // localPosition = Offset(localPosition.dx * _theZoomVal - imgSpaceWidthOfSingle, localPosition.dy / _theZoomVal);
+ } else {
+ localPosition = Offset(localPosition.dx, localPosition.dy + _dy);
+ }
+
+ var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser, data: localPosition));
+ var newVal1 = ref.read(drawMarkingProvider).offsets..add(localPosition);
+ ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal, newVal1));
+ widget.callAnnotationTips();
+ },
+ // onPointerDown: (PointerDownEvent event) {
+ // },
+ onPointerUp: (PointerUpEvent details) {
+ if (btnEnum != ReviewMarksBottomBtnsEnum.HANDWRITING) return;
+ // 如果在空白区域 非试题图片区域就返回
+ if (illegalArea) return;
+
+ globalPosition = null;
+
+ var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
+ var newVal1 = ref.read(drawMarkingProvider).offsets..add(null);
+ ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal, newVal1));
+ },
+ child: IgnorePointer(
+ ignoring: btnEnum != ReviewMarksBottomBtnsEnum.DRAG,
+ child: Zoom(
+ key: _zoomKey,
+ // 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 != null ? (imagInfoModel!.scaleHeight! / imagInfoModel!.zoom) : null,
+ initScale: initScale ?? 1,
+ initPosition: zoomOffset,
+ onScaleUpdate: onScaleUpdate,
+ onPositionUpdate: onPanUpPosition,
+ ),
+ ),
);
},
);
@@ -303,24 +475,17 @@ class PictureOverviewState extends ConsumerState with CommonMix
// 试卷绘制
class ExamPaperDrawing extends StatefulHookConsumerWidget {
- String imgUrl;
- bool homework;
+ // String imgUrl;
+ Widget child;
BoxDecoration? decoration;
AnnotationGraffitiSwitch graffitiSwitch;
- List? points;
- List? pointsPureData;
- ValueNotifier