diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart index a4e76e7..141067d 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart @@ -518,7 +518,7 @@ class QuestionImageView extends HookWidget with EventBusMixin 0) { activePointers.value = activePointers.value - 1; } - print("---进入:onPointerUp ${activePointers.value}"); + // 移除高频日志,避免导致掉帧 timerRef.value?.cancel(); if (!annotationState.pen.value) return; @@ -526,7 +526,7 @@ class QuestionImageView extends HookWidget with EventBusMixin 图片坐标(通过逆矩阵) - final inv = Matrix4.inverted(matrix); - final v = inv.transform3(Vector3(localPosition.dx, localPosition.dy, 0)); - localPosition = Offset(v.x, v.y); + // final inv = Matrix4.inverted(matrix); + // final v = inv.transform3(Vector3(localPosition.dx, localPosition.dy, 0)); + // localPosition = Offset(v.x, v.y); + + /// 屏幕坐标 -> 图片坐标(通过逆矩阵)。当无缩放/平移时走快速路径,避免不必要求逆 + /// 它们是 Matrix4 内部 4x4 矩阵的平移分量(列主序存储)。 + /// storage[12] 是平移的 x 分量,storage[13] 是平移的 y 分量(storage[14] 则是 z)。 + /// 因为 Matrix4 采用列主序,索引计算为 index = col * 4 + row,平移在第 4 列的前 3 行,所以是 12、13、14。 + /// 用途:当 theScale == 1.0 && storage[12] == 0.0 && storage[13] == 0.0 时,可判定无缩放/平移,走快速路径跳过逆矩阵。 + final double tx = matrix.storage[12]; + final double ty = matrix.storage[13]; + if (theScale == 1.0 && tx == 0.0 && ty == 0.0) { + // identity 变换,局部坐标无需转换 + } else { + final inv = Matrix4.inverted(matrix); + final v = inv.transform3(Vector3(localPosition.dx, localPosition.dy, 0)); + localPosition = Offset(v.x, v.y); + } // 在图片坐标系做边界校验(更直观):0..maxWidth、0..actualHeight if (localPosition.dy < 0 || localPosition.dy > actualHeight) return; @@ -625,7 +640,8 @@ class QuestionImageView extends HookWidget with EventBusMixin points = ctrl.value; + if (points.isEmpty) return; + + Path path = Path(); + Offset? previous; + for (int i = 0; i < points.length; i++) { + final Offset? current = points[i] as Offset?; + if (current == null) { + // 提交当前子路径 + if (path.computeMetrics().isNotEmpty) { + canvas.drawPath(path, paintBrush); + } + path = Path(); + previous = null; + continue; } + if (previous == null) { + path.moveTo(current.dx, current.dy); + } else { + path.lineTo(current.dx, current.dy); + } + previous = current; + } + // 绘制最后的子路径 + if (path.computeMetrics().isNotEmpty) { + canvas.drawPath(path, paintBrush); } }