瀏覽代碼

AutoSnapMixin

melon.yin 2 年之前
父節點
當前提交
b86d90647c

+ 6 - 0
lib/interfaces/date_types/int_size.dart

@@ -1,3 +1,5 @@
+import 'package:flutter/painting.dart';
+
 class IntSize {
   static final IntSize empty = IntSize();
 
@@ -31,6 +33,10 @@ class IntSize {
     _height = value;
   }
 
+  Size toDoubleSize() {
+    return Size(width.toDouble(), height.toDouble());
+  }
+
   @override
   bool operator ==(Object other) {
     return other is IntSize &&

+ 7 - 5
lib/process/primitives/polyline.dart

@@ -3,16 +3,16 @@ import 'dart:ui';
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/enums/items.dart';
 import 'package:fis_measure/interfaces/process/items/item_metas.dart';
-
 import 'package:fis_measure/interfaces/process/items/item.dart';
 import 'package:fis_measure/interfaces/process/items/types.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
 import 'package:fis_measure/process/calcuators/calculator.dart';
 import 'package:fis_measure/process/items/item.dart';
 import 'package:fis_measure/process/items/item_feature.dart';
+import 'package:fis_measure/process/primitives/utils/auto_snap.dart';
 import 'package:fis_measure/utils/canvas.dart';
 
-class Polyline extends MeasureItem<PolylineFeature> {
+class Polyline extends MeasureItem<PolylineFeature> with AutoSnapMixin {
   Polyline(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
 
   static Polyline createAreaPerimeter(ItemMeta meta, [IMeasureItem? parent]) {
@@ -46,9 +46,11 @@ class Polyline extends MeasureItem<PolylineFeature> {
       }
       doCalculate();
 
-      if (f.startPoint.almostEquals(f.endPoint)) {
-        doFeatureFinish();
-      }
+      checkAutoFinish(args);
+
+      // if (f.startPoint.almostEquals(f.endPoint)) {
+      //   doFeatureFinish();
+      // }
     }
     return true;
   }

+ 7 - 41
lib/process/primitives/trace.dart

@@ -5,6 +5,7 @@ import 'package:fis_measure/interfaces/enums/items.dart';
 import 'package:fis_measure/interfaces/process/items/item.dart';
 import 'package:fis_measure/interfaces/process/items/item_metas.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
+import 'package:fis_measure/process/primitives/utils/auto_snap.dart';
 import 'package:fis_measure/utils/canvas.dart';
 import 'package:flutter/services.dart';
 import 'package:path_drawing/path_drawing.dart';
@@ -14,7 +15,7 @@ import '../calcuators/perimeter.dart';
 import '../items/item.dart';
 import '../items/item_feature.dart';
 
-class Trace extends MeasureItem<TraceFeature> {
+class Trace extends MeasureItem<TraceFeature> with AutoSnapMixin {
   final bool _initialClosed = false;
   PointInfo? _firstPoint;
 
@@ -40,44 +41,18 @@ class Trace extends MeasureItem<TraceFeature> {
       if (args.pointType == PointInfoType.mouseDown) {
         doFeatureFinish();
       } else {
-        _checkAutoFinish(args);
+        checkAutoFinish(args);
       }
     }
     return true;
   }
 
-  void _doFinish() {
-    doFeatureFinish();
+  @override
+  void doFeatureFinish() {
+    super.doFeatureFinish();
     _firstPoint = null;
   }
 
-  void _checkAutoFinish(PointInfo current) {
-    if (feature == null || feature!.innerPoints.length < 3) return;
-
-    double autoSnapDistance = 0.01; //TODO: from config
-    double autoSnapThreshold = 0.05;
-    bool isAutoSnap = true; //TODO: from config
-    if (isAutoSnap == false) return;
-
-    // final viewport = feature!.hostVisualArea!.viewport!;
-    var length = (feature!.firstPoint - current).length;
-    if (length > autoSnapThreshold * 2.0 && !feature!.isSmartMove) {
-      feature!.isSmartMove = true;
-    }
-    if (length < autoSnapThreshold && feature!.isSmartMove) {
-      HapticFeedback.heavyImpact();
-      _doFinish();
-    }
-    // final logicStart = feature!.innerPoints.first;
-    // final logicEnd = feature!.innerPoints.last;
-
-    // // isSmartMove
-    // if (logicEnd.almostEquals(logicStart, 0.01)) {
-    //   feature!.innerPoints.add(feature!.innerPoints.first); // 强制闭合
-    //   doFeatureFinish();
-    // }
-  }
-
   void handleMouseDownWhileWaiting(PointInfo args) {
     // TODO: 判断是否当前area
     // 转换为Area逻辑位置
@@ -121,7 +96,7 @@ class Trace extends MeasureItem<TraceFeature> {
       if (args.pointType == PointInfoType.touchMove) {
         feature?.adopt(args);
         doCalculate();
-        _checkAutoFinish(args);
+        checkAutoFinish(args);
       }
     }
     return true;
@@ -150,7 +125,6 @@ class Trace extends MeasureItem<TraceFeature> {
 
 class TraceFeature extends MeasureItemFeature {
   bool _isClosed = false;
-  bool _isSmartMove = false;
 
   TraceFeature(IMeasureItem refItem) : super(refItem);
 
@@ -162,14 +136,6 @@ class TraceFeature extends MeasureItemFeature {
     }
   }
 
-  /// 是否启动智能定位
-  bool get isSmartMove => _isSmartMove;
-  set isSmartMove(bool value) {
-    if (value != _isSmartMove) {
-      _isSmartMove = value;
-    }
-  }
-
   /// 首节点
   DPoint get firstPoint => innerPoints.first;
 

+ 51 - 0
lib/process/primitives/utils/auto_snap.dart

@@ -0,0 +1,51 @@
+import 'package:fis_measure/interfaces/date_types/int_size.dart';
+import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
+import 'package:fis_measure/process/items/item.dart';
+import 'package:fis_measure/process/items/item_feature.dart';
+import 'package:flutter/painting.dart';
+import 'package:flutter/services.dart';
+
+mixin AutoSnapMixin<T extends MeasureItemFeature> on MeasureItem<T> {
+  bool _isSmartMove = false;
+
+  /// 是否启动智能定位
+  bool get isSmartMove => _isSmartMove;
+  set isSmartMove(bool value) {
+    if (value != _isSmartMove) {
+      _isSmartMove = value;
+    }
+  }
+
+  /// 自动结束检测
+  bool checkAutoFinish(PointInfo current) {
+    if (feature == null || feature!.innerPoints.length < 3) {
+      isSmartMove = false;
+      return false;
+    }
+
+    // final viewport = feature!.hostVisualArea!.viewport!;
+
+    double autoSnapThreshold = 10; //TODO: from config, pixel
+    bool isAutoSnap = true; //TODO: from config
+    if (isAutoSnap == false) return false;
+    final pixelSize = IntSize.fill(
+      application.frameData!.width,
+      application.frameData!.height,
+    ).toDoubleSize();
+
+    final p1 = feature!.innerPoints.first.scale2Size(pixelSize);
+    final p2 = current.scale2Size(pixelSize);
+    final length = (p1 - p2).length;
+    if (length > autoSnapThreshold * 2.0 && !isSmartMove) {
+      isSmartMove = true;
+    }
+    if (length < autoSnapThreshold && isSmartMove) {
+      HapticFeedback.heavyImpact();
+      doFeatureFinish();
+      isSmartMove = false;
+      return true;
+    } else {
+      return false;
+    }
+  }
+}