import 'package:fis_measure/values/colors.dart'; import 'package:fis_measure/view/gesture/positioned_cursor.dart'; import 'package:fis_measure/view/gesture/positioned_touch_cursor.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:path_drawing/path_drawing.dart'; class CrossIndicator extends StatefulWidget { const CrossIndicator({Key? key, required this.areaRegion}) : super(key: key); final Rect areaRegion; @override State createState() => CrossIndicatorState(); } class CrossIndicatorState extends State { final mouseState = Get.find(); CrossIndicatorStyle indicatorStyle = CrossIndicatorStyle.nomal; @override void initState() { mouseState.mousePositionChanged.addListener(mousePositionChanged); mouseState.crossIndicatorStyleChanged .addListener(_crossIndicatorStyleChanged); super.initState(); } @override void dispose() { mouseState.mousePositionChanged.removeListener(mousePositionChanged); mouseState.crossIndicatorStyleChanged .removeListener(_crossIndicatorStyleChanged); super.dispose(); } @override Widget build(BuildContext context) { final position = mouseState.mousePosition; if (position == null) return Container(); return Positioned( top: widget.areaRegion.top, width: widget.areaRegion.width, height: widget.areaRegion.height, child: RepaintBoundary( child: CustomPaint( painter: _CrossIndicatorPainter( color: MeasureColors.Primary, centerOffset: Offset(position.dx, position.dy - widget.areaRegion.top), style: indicatorStyle)), ), ); } void mousePositionChanged(Object sender, dynamic e) { onUpdate(); } void _crossIndicatorStyleChanged(Object sender, dynamic e) { setState(() { indicatorStyle = e; }); } void onUpdate() { setState(() {}); } } class MobileCrossIndicator extends StatefulWidget { const MobileCrossIndicator({Key? key, required this.areaRegion}) : super(key: key); final Rect areaRegion; @override State createState() => MobileCrossIndicatorState(); } class MobileCrossIndicatorState extends State { final touchState = Get.find(); CrossIndicatorStyle indicatorStyle = CrossIndicatorStyle.nomal; @override void initState() { touchState.mousePositionChanged.addListener(mousePositionChanged); touchState.crossIndicatorStyleChanged .addListener(_crossIndicatorStyleChanged); super.initState(); } @override void dispose() { touchState.mousePositionChanged.removeListener(mousePositionChanged); touchState.crossIndicatorStyleChanged .removeListener(_crossIndicatorStyleChanged); super.dispose(); } @override Widget build(BuildContext context) { final position = touchState.touchPosition; if (position == null) return Container(); final centerOffset = position + touchState.touchOffset; return Positioned( top: widget.areaRegion.top, width: widget.areaRegion.width, height: widget.areaRegion.height, child: RepaintBoundary( child: CustomPaint( painter: _CrossIndicatorPainter( strokeWidth: 1, color: MeasureColors.ActiveCaliper, centerOffset: Offset( centerOffset.dx, centerOffset.dy - widget.areaRegion.top), style: indicatorStyle)), ), ); } void mousePositionChanged(Object sender, dynamic e) { onUpdate(); } void _crossIndicatorStyleChanged(Object sender, dynamic e) { setState(() { indicatorStyle = e; }); } void onUpdate() { setState(() {}); } } class _CrossIndicatorPainter extends CustomPainter { const _CrossIndicatorPainter( {this.color, this.strokeWidth, this.centerOffset, this.style = CrossIndicatorStyle.nomal}); final Color? color; final double? strokeWidth; final Offset? centerOffset; final CrossIndicatorStyle style; @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = color ?? const Color.fromARGB(255, 255, 255, 0) ..strokeWidth = strokeWidth ?? 2 ..style = PaintingStyle.stroke ..isAntiAlias = false; final center = centerOffset ?? Offset(size.width / 2, size.height / 2); //绘制十字点路径 final path = Path(); switch (style) { case CrossIndicatorStyle.nomal: path ..moveTo(center.dx, 0) ..lineTo(center.dx, size.height) ..moveTo(0, center.dy) ..lineTo(size.width, center.dy); break; case CrossIndicatorStyle.vertical: path ..moveTo(center.dx, 0) ..lineTo(center.dx, size.height); break; case CrossIndicatorStyle.horizontal: path ..moveTo(0, center.dy) ..lineTo(size.width, center.dy); break; } canvas.drawPath( dashPath( path, dashArray: CircularIntervalList([5, 10]), ), paint); } @override bool shouldRepaint(covariant _CrossIndicatorPainter oldDelegate) { return oldDelegate.color != color || oldDelegate.centerOffset != centerOffset || oldDelegate.style != style; } } enum CrossIndicatorStyle { ///标准状态 nomal, //仅横指示线 horizontal, //仅纵指示线 vertical, }