cross_position_indicator.dart 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import 'package:fis_measure/values/colors.dart';
  2. import 'package:fis_measure/view/gesture/positioned_cursor.dart';
  3. import 'package:fis_measure/view/gesture/positioned_touch_cursor.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:get/get.dart';
  6. import 'package:path_drawing/path_drawing.dart';
  7. class CrossIndicator extends StatefulWidget {
  8. const CrossIndicator({Key? key, required this.areaRegion}) : super(key: key);
  9. final Rect areaRegion;
  10. @override
  11. State<StatefulWidget> createState() => CrossIndicatorState();
  12. }
  13. class CrossIndicatorState extends State<CrossIndicator> {
  14. final mouseState = Get.find<IMouseState>();
  15. CrossIndicatorStyle indicatorStyle = CrossIndicatorStyle.nomal;
  16. @override
  17. void initState() {
  18. mouseState.mousePositionChanged.addListener(mousePositionChanged);
  19. mouseState.crossIndicatorStyleChanged
  20. .addListener(_crossIndicatorStyleChanged);
  21. super.initState();
  22. }
  23. @override
  24. void dispose() {
  25. mouseState.mousePositionChanged.removeListener(mousePositionChanged);
  26. mouseState.crossIndicatorStyleChanged
  27. .removeListener(_crossIndicatorStyleChanged);
  28. super.dispose();
  29. }
  30. @override
  31. Widget build(BuildContext context) {
  32. final position = mouseState.mousePosition;
  33. if (position == null) return Container();
  34. return Positioned(
  35. top: widget.areaRegion.top,
  36. width: widget.areaRegion.width,
  37. height: widget.areaRegion.height,
  38. child: RepaintBoundary(
  39. child: CustomPaint(
  40. painter: _CrossIndicatorPainter(
  41. color: MeasureColors.Primary,
  42. centerOffset:
  43. Offset(position.dx, position.dy - widget.areaRegion.top),
  44. style: indicatorStyle)),
  45. ),
  46. );
  47. }
  48. void mousePositionChanged(Object sender, dynamic e) {
  49. onUpdate();
  50. }
  51. void _crossIndicatorStyleChanged(Object sender, dynamic e) {
  52. setState(() {
  53. indicatorStyle = e;
  54. });
  55. }
  56. void onUpdate() {
  57. setState(() {});
  58. }
  59. }
  60. class MobileCrossIndicator extends StatefulWidget {
  61. const MobileCrossIndicator({Key? key, required this.areaRegion})
  62. : super(key: key);
  63. final Rect areaRegion;
  64. @override
  65. State<StatefulWidget> createState() => MobileCrossIndicatorState();
  66. }
  67. class MobileCrossIndicatorState extends State<MobileCrossIndicator> {
  68. final touchState = Get.find<ITouchPointState>();
  69. CrossIndicatorStyle indicatorStyle = CrossIndicatorStyle.nomal;
  70. @override
  71. void initState() {
  72. touchState.mousePositionChanged.addListener(mousePositionChanged);
  73. touchState.crossIndicatorStyleChanged
  74. .addListener(_crossIndicatorStyleChanged);
  75. super.initState();
  76. }
  77. @override
  78. void dispose() {
  79. touchState.mousePositionChanged.removeListener(mousePositionChanged);
  80. touchState.crossIndicatorStyleChanged
  81. .removeListener(_crossIndicatorStyleChanged);
  82. super.dispose();
  83. }
  84. @override
  85. Widget build(BuildContext context) {
  86. final position = touchState.touchPosition;
  87. if (position == null) return Container();
  88. final centerOffset = position + touchState.touchOffset;
  89. return Positioned(
  90. top: widget.areaRegion.top,
  91. width: widget.areaRegion.width,
  92. height: widget.areaRegion.height,
  93. child: RepaintBoundary(
  94. child: CustomPaint(
  95. painter: _CrossIndicatorPainter(
  96. strokeWidth: 1,
  97. color: MeasureColors.ActiveCaliper,
  98. centerOffset: Offset(
  99. centerOffset.dx, centerOffset.dy - widget.areaRegion.top),
  100. style: indicatorStyle)),
  101. ),
  102. );
  103. }
  104. void mousePositionChanged(Object sender, dynamic e) {
  105. onUpdate();
  106. }
  107. void _crossIndicatorStyleChanged(Object sender, dynamic e) {
  108. setState(() {
  109. indicatorStyle = e;
  110. });
  111. }
  112. void onUpdate() {
  113. setState(() {});
  114. }
  115. }
  116. class _CrossIndicatorPainter extends CustomPainter {
  117. const _CrossIndicatorPainter(
  118. {this.color,
  119. this.strokeWidth,
  120. this.centerOffset,
  121. this.style = CrossIndicatorStyle.nomal});
  122. final Color? color;
  123. final double? strokeWidth;
  124. final Offset? centerOffset;
  125. final CrossIndicatorStyle style;
  126. @override
  127. void paint(Canvas canvas, Size size) {
  128. final paint = Paint()
  129. ..color = color ?? const Color.fromARGB(255, 255, 255, 0)
  130. ..strokeWidth = strokeWidth ?? 2
  131. ..style = PaintingStyle.stroke
  132. ..isAntiAlias = false;
  133. final center = centerOffset ?? Offset(size.width / 2, size.height / 2);
  134. //绘制十字点路径
  135. final path = Path();
  136. switch (style) {
  137. case CrossIndicatorStyle.nomal:
  138. path
  139. ..moveTo(center.dx, 0)
  140. ..lineTo(center.dx, size.height)
  141. ..moveTo(0, center.dy)
  142. ..lineTo(size.width, center.dy);
  143. break;
  144. case CrossIndicatorStyle.vertical:
  145. path
  146. ..moveTo(center.dx, 0)
  147. ..lineTo(center.dx, size.height);
  148. break;
  149. case CrossIndicatorStyle.horizontal:
  150. path
  151. ..moveTo(0, center.dy)
  152. ..lineTo(size.width, center.dy);
  153. break;
  154. }
  155. canvas.drawPath(
  156. dashPath(
  157. path,
  158. dashArray: CircularIntervalList<double>([5, 10]),
  159. ),
  160. paint);
  161. }
  162. @override
  163. bool shouldRepaint(covariant _CrossIndicatorPainter oldDelegate) {
  164. return oldDelegate.color != color ||
  165. oldDelegate.centerOffset != centerOffset ||
  166. oldDelegate.style != style;
  167. }
  168. }
  169. enum CrossIndicatorStyle {
  170. ///标准状态
  171. nomal,
  172. //仅横指示线
  173. horizontal,
  174. //仅纵指示线
  175. vertical,
  176. }