calibration_canvas.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import 'dart:math';
  2. import 'package:fis_measure/interfaces/date_types/point.dart';
  3. import 'package:fis_measure/interfaces/process/standard_line/calibration.dart';
  4. import 'package:fis_measure/utils/canvas.dart';
  5. import 'package:fis_measure/values/colors.dart';
  6. import 'package:flutter/material.dart';
  7. /// 参考线画布
  8. ///
  9. /// [controller] 校准线控制器
  10. class StandardLineCalibrationCanvas extends StatefulWidget {
  11. const StandardLineCalibrationCanvas(this.controller, {Key? key})
  12. : super(key: key);
  13. final IStandardLineCalibrationController controller;
  14. @override
  15. State<StandardLineCalibrationCanvas> createState() => _CanvasState();
  16. }
  17. class _CanvasState extends State<StandardLineCalibrationCanvas> {
  18. late IStandardLineCalibrationController controller;
  19. @override
  20. void initState() {
  21. controller = widget.controller;
  22. controller.updateReady.addListener(_onUpdateReady);
  23. super.initState();
  24. }
  25. @override
  26. void dispose() {
  27. controller.updateReady.removeListener(_onUpdateReady);
  28. super.dispose();
  29. }
  30. @override
  31. Widget build(BuildContext context) {
  32. return LayoutBuilder(builder: (context, constraints) {
  33. CustomPainter painter;
  34. if (controller.isEditing) {
  35. painter = _EditingPainter(controller.drawPoints);
  36. } else {
  37. painter = _ViewLinePainter(
  38. length: controller.displayLengthInPhysics,
  39. bottom: 3,
  40. );
  41. }
  42. return ClipRect(
  43. child: SizedBox(
  44. width: constraints.maxWidth,
  45. height: constraints.maxHeight,
  46. child: RepaintBoundary(
  47. child: CustomPaint(
  48. painter: painter,
  49. ),
  50. ),
  51. ),
  52. );
  53. });
  54. }
  55. void _onUpdateReady(Object sender, void e) {
  56. if (controller.editState == StandardLineCalibrationEditState.drawing) {
  57. setState(() {});
  58. }
  59. }
  60. }
  61. class _EditingPainter extends CustomPainter {
  62. // ignore: constant_identifier_names
  63. static const double C_VERTEX_SIZE = 10;
  64. _EditingPainter(this.points);
  65. final List<DPoint> points;
  66. final _paintPan = Paint()
  67. ..color = MeasureColors.ActiveCaliper
  68. ..style = PaintingStyle.stroke
  69. ..strokeWidth = 2;
  70. @override
  71. void paint(Canvas canvas, Size size) {
  72. if (points.length < 2) return;
  73. final startOffset = points[0].scale2Size(size).toOffset();
  74. final endOffset = points[1].scale2Size(size).toOffset();
  75. canvas.drawVertex(startOffset, C_VERTEX_SIZE, active: true);
  76. canvas.drawLine(startOffset, endOffset, _paintPan);
  77. canvas.drawVertex(endOffset, C_VERTEX_SIZE, active: true);
  78. }
  79. @override
  80. bool shouldRepaint(covariant _EditingPainter oldDelegate) {
  81. return this != oldDelegate;
  82. }
  83. }
  84. class _ViewLinePainter extends CustomPainter {
  85. // ignore: constant_identifier_names
  86. static const C_MARK_HEIGHT = 2;
  87. _ViewLinePainter({
  88. required this.length,
  89. required this.bottom,
  90. this.physicalLength = 4,
  91. });
  92. final double length;
  93. final double bottom;
  94. final int physicalLength;
  95. final _paintPan = Paint()
  96. ..color = Colors.red //MeasureColors.Primary
  97. ..style = PaintingStyle.stroke
  98. ..strokeWidth = 2;
  99. /// 刻度文案【4cm】预留的宽度
  100. static const double _textWidth = 80;
  101. @override
  102. void paint(Canvas canvas, Size size) {
  103. //画布可容纳的最大刻度数
  104. final fittedPhysicalLength = (size.width - _textWidth) ~/ length;
  105. //如果画布可容纳的最大刻度数小于预设刻度数,则需要缩刻度数,防止标尺超出图像
  106. final _physicalLength = min(fittedPhysicalLength, physicalLength);
  107. final markHeight = (C_MARK_HEIGHT / 100) * size.height;
  108. final lineLength = length * _physicalLength;
  109. final left = (size.width - lineLength) / 2;
  110. final top = (100 - bottom) / 100 * size.height;
  111. Offset position = Offset(left, top);
  112. for (var i = 0; i < _physicalLength; i++) {
  113. final p1 = position.translate(length * i, 0);
  114. final p2 = p1.translate(length, 0);
  115. final mark = p2.translate(0, -markHeight);
  116. canvas.drawLine(p1, p2, _paintPan);
  117. canvas.drawLine(p2, mark, _paintPan);
  118. if (i == 0) {
  119. canvas.drawLine(p1, p1.translate(0, -markHeight), _paintPan);
  120. }
  121. }
  122. final tipSize = markHeight * 1.1;
  123. final tipPosition = Offset(left + lineLength + markHeight, top - tipSize);
  124. canvas.drawText(
  125. '${_physicalLength}cm',
  126. tipPosition,
  127. style: TextStyle(
  128. fontSize: tipSize,
  129. fontWeight: FontWeight.bold,
  130. color: Colors.red,
  131. ),
  132. );
  133. }
  134. @override
  135. bool shouldRepaint(covariant CustomPainter oldDelegate) {
  136. return false;
  137. }
  138. }