@fleet-frontend/mower-maps 0.2.0-beta.12 → 0.2.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -293,7 +293,7 @@ function initObstacle() {
293
293
  const obstacle = {
294
294
  id: null,
295
295
  area: 0,
296
- name: 'off-imit island',
296
+ name: 'Noname',
297
297
  status: 1,
298
298
  end_timestamp: 0,
299
299
  start_timestamp: 0,
@@ -15072,10 +15072,10 @@ const DashPath = ({ points, stroke, strokeWidth, strokeOpacity, className, }) =>
15072
15072
  return (jsxs(Fragment, { children: [jsx("path", { fill: "none", d: parallelPath2Data, stroke: stroke, strokeWidth: strokeWidth, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", strokeDasharray: `${strokeWidth}px ${strokeWidth * 2}px`, style: { pointerEvents: 'none' } }), jsx("path", { fill: "none", d: parallelPath1Data, stroke: stroke, strokeWidth: strokeWidth, strokeOpacity: strokeOpacity, strokeLinecap: "round", strokeLinejoin: "round", strokeDasharray: `${strokeWidth}px ${strokeWidth * 2}px`, style: { pointerEvents: 'none' } })] }));
15073
15073
  };
15074
15074
 
15075
- const VertexElement = React__default.memo(({ r, stroke, ...props }) => {
15076
- const { overlayScale } = useCommonContext();
15075
+ const VertexElement = React__default.memo(({ r, stroke, fill, ...props }) => {
15076
+ const { overlayScale, platform } = useCommonContext();
15077
15077
  const radius = typeof r === 'number' ? r : 12;
15078
- return (jsx("circle", { r: radius * overlayScale, stroke: stroke || '#fff', fill: '#fff', strokeWidth: 2 * overlayScale, ...props }));
15078
+ return (jsx("circle", { r: platform === PlatformType.H5 ? (radius * overlayScale) / 2 : radius * overlayScale, stroke: stroke || '#fff', fill: fill || '#fff', strokeWidth: 2 * overlayScale, ...props }));
15079
15079
  });
15080
15080
 
15081
15081
  var _path$2;
@@ -15159,6 +15159,7 @@ const normalizePadding = (padding) => {
15159
15159
  return { x: padding?.x ?? 4, y: padding?.y ?? 2 };
15160
15160
  };
15161
15161
  const TextElement = ({ x, y, fontSize = 30, fill = '#fff', text, background = 'rgba(0, 0, 0, 0.34)', padding = 2, rx = 4, ry = 4, backgroundStroke, backgroundStrokeWidth = 0, textAnchor = 'middle', alignmentBaseline = 'middle', className, style, rotate, pointerEvents = 'auto', onClick, onMouseEnter, onMouseLeave, children, }) => {
15162
+ const { platform } = useCommonContext();
15162
15163
  const textRef = useRef(null);
15163
15164
  const [bbox, setBbox] = useState(null);
15164
15165
  const pad = useMemo(() => normalizePadding(padding), [padding]);
@@ -15185,7 +15186,7 @@ const TextElement = ({ x, y, fontSize = 30, fill = '#fff', text, background = 'r
15185
15186
  height: bbox.height + pad.y * 2,
15186
15187
  };
15187
15188
  }, [bbox, pad.x, pad.y]);
15188
- return (jsxs("g", { className: className, style: style, pointerEvents: pointerEvents, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, children: [background && rectProps && (jsx("rect", { x: rectProps.x, y: rectProps.y, width: rectProps.width, height: rectProps.height, rx: rx, ry: ry, fill: background, stroke: backgroundStroke, strokeWidth: backgroundStrokeWidth })), jsx("text", { ref: textRef, x: x, y: y, letterSpacing: -5, fontSize: fontSize, fill: fill, textAnchor: textAnchor, alignmentBaseline: alignmentBaseline,
15189
+ return (jsxs("g", { className: className, style: style, pointerEvents: pointerEvents, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, children: [background && rectProps && (jsx("rect", { x: rectProps.x, y: rectProps.y, width: rectProps.width, height: rectProps.height, rx: rx, ry: ry, fill: background, stroke: backgroundStroke, strokeWidth: backgroundStrokeWidth })), jsx("text", { ref: textRef, x: x, y: y, letterSpacing: platform === PlatformType.H5 ? 1 : -5, fontSize: fontSize, fill: fill, textAnchor: textAnchor, alignmentBaseline: alignmentBaseline,
15189
15190
  // keep text crisp at various zoom levels
15190
15191
  vectorEffect: "non-scaling-stroke", style: { pointerEvents: 'none' }, children: children || text })] }));
15191
15192
  };
@@ -15215,7 +15216,7 @@ const calculateMidpoint$1 = (point1, point2) => {
15215
15216
  const DistanceLabels = ({ coordinates, createMode = false, editMode = false, completed = false, showPoints = false, mousePos: _mousePos = null, ghostLastDistance = null, ghostLastMidpoint = null, ghostFirstDistance = null, ghostFirstMidpoint = null, fontSize = 30, }) => {
15216
15217
  // 只在显示可操作顶点时显示距离
15217
15218
  if (!((createMode && showPoints) || editMode || (createMode && completed)) ||
15218
- coordinates.length < 1) {
15219
+ coordinates.length < 2) {
15219
15220
  return null;
15220
15221
  }
15221
15222
  return (jsxs(Fragment, { children: [coordinates.map((coord, idx) => {
@@ -15230,8 +15231,22 @@ const DistanceLabels = ({ coordinates, createMode = false, editMode = false, com
15230
15231
  return (jsx(TextElement, { x: midpoint[0], y: midpoint[1], textAnchor: "middle", alignmentBaseline: "middle", fontSize: fontSize, fill: "#fff", style: {
15231
15232
  pointerEvents: 'none',
15232
15233
  fontWeight: 'bold',
15234
+ userSelect: 'none',
15235
+ WebkitUserSelect: 'none',
15236
+ WebkitTouchCallout: 'none',
15237
+ touchAction: 'none',
15233
15238
  }, text: distance }, `distance-${idx}`));
15234
- }), ghostLastDistance && ghostLastMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostLastMidpoint[0], y: ghostLastMidpoint[1], text: ghostLastDistance })), ghostFirstDistance && ghostFirstMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostFirstMidpoint[0], y: ghostFirstMidpoint[1], text: ghostFirstDistance }))] }));
15239
+ }), ghostLastDistance && ghostLastMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostLastMidpoint[0], y: ghostLastMidpoint[1], text: ghostLastDistance, style: {
15240
+ userSelect: 'none',
15241
+ WebkitUserSelect: 'none',
15242
+ WebkitTouchCallout: 'none',
15243
+ touchAction: 'none',
15244
+ } })), ghostFirstDistance && ghostFirstMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostFirstMidpoint[0], y: ghostFirstMidpoint[1], text: ghostFirstDistance, style: {
15245
+ userSelect: 'none',
15246
+ WebkitUserSelect: 'none',
15247
+ WebkitTouchCallout: 'none',
15248
+ touchAction: 'none',
15249
+ } }))] }));
15235
15250
  };
15236
15251
 
15237
15252
  var css_248z$2 = ".index-module_polygonPathG__S-Bpl {\n pointer-events: stroke;\n cursor: pointer;\n}\n\n.index-module_vertex__-Qb1u {\n cursor: pointer;\n}\n\n.index-module_dragging__xSFdO {\n cursor: grabbing;\n}\n\n.index-module_createVertex__ldz2E {\n cursor: crosshair;\n}\n\n.index-module_addVertex__hrF71 {\n cursor: pointer;\n}\n\n.index-module_polygonPath__PynOn {\n pointer-events: stroke;\n cursor: pointer;\n}\n\n.index-module_notCreate__bFnkV {\n cursor: no-drop;\n}";
@@ -15527,6 +15542,7 @@ function coordinatesToPoints$1(coordinates) {
15527
15542
 
15528
15543
  const useCheckElement = () => {
15529
15544
  const { editMapInfo, minDistance } = useMapEditContext();
15545
+ const { platform } = useCommonContext();
15530
15546
  const { svgElementDatas } = useSvgEditContext();
15531
15547
  const checkDoodle = useCallback(() => {
15532
15548
  console.log('checkdoodle', editMapInfo, svgElementDatas);
@@ -15627,7 +15643,7 @@ const useCheckElement = () => {
15627
15643
  return { isValid: true };
15628
15644
  }, [editMapInfo, svgElementDatas, minDistance]);
15629
15645
  const checkCanNotCreateAtPosition = useCallback((checkPoint, checkPoints) => {
15630
- console.log('editMapInfo.elementType--->', editMapInfo);
15646
+ // console.log('editMapInfo.elementType--->', editMapInfo);
15631
15647
  if (!editMapInfo.elementType)
15632
15648
  return false;
15633
15649
  const currentPoints = editMapInfo?.selectElement?.points;
@@ -15654,8 +15670,10 @@ const useCheckElement = () => {
15654
15670
  return false;
15655
15671
  // 获取当前正在创建的 obstacle 的点
15656
15672
  const currentObstaclePoints = coordinatesToPoints$1(points) || [];
15657
- if (currentObstaclePoints.length === 0)
15658
- return false; // 还没有开始绘制
15673
+ if (platform !== PlatformType.H5) {
15674
+ if (currentObstaclePoints.length === 0)
15675
+ return false; // 还没有开始绘制
15676
+ }
15659
15677
  // 构建当前 obstacle 的多边形(包括检查点位置)
15660
15678
  const currentObstaclePolygon = [...currentObstaclePoints, checkPoint];
15661
15679
  // 获取当前边界内的所有元素
@@ -15811,6 +15829,8 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15811
15829
  });
15812
15830
  // 虚拟顶点hover状态
15813
15831
  const [hoverVertex, setHoverVertex] = useState(null);
15832
+ // H5平台选中的顶点索引(长按后选中)
15833
+ const [selectedVertexIndex, setSelectedVertexIndex] = useState(-1);
15814
15834
  const { checkCanNotCreateAtPosition } = useCheckElement();
15815
15835
  const { editMapInfo } = useMapEditContext();
15816
15836
  const { platform } = useCommonContext();
@@ -15878,11 +15898,33 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15878
15898
  if (tooltipIndex !== null)
15879
15899
  setTooltipIndex(null);
15880
15900
  }, [editMode, createMode, completed]);
15901
+ // H5平台:点击空白处取消选中状态
15902
+ useEffect(() => {
15903
+ if (platform !== PlatformType.H5 || selectedVertexIndex === -1)
15904
+ return;
15905
+ const handleDocumentClick = (e) => {
15906
+ // 检查点击的目标是否是顶点
15907
+ const target = e.target;
15908
+ const isClickingVertex = target.closest('circle') !== null;
15909
+ // 如果点击的不是顶点,则取消选中状态
15910
+ if (!isClickingVertex) {
15911
+ setSelectedVertexIndex(-1);
15912
+ }
15913
+ };
15914
+ document.addEventListener('click', handleDocumentClick);
15915
+ return () => {
15916
+ document.removeEventListener('click', handleDocumentClick);
15917
+ };
15918
+ }, [platform, selectedVertexIndex]);
15881
15919
  // 处理顶点拖拽
15882
15920
  const handleVertexMouseDown = useCallback((e, index) => {
15883
15921
  // 只有在编辑模式或者创建模式已完成时才能拖拽
15884
15922
  if (!editMode && !(createMode && completed))
15885
15923
  return;
15924
+ // H5模式下,只有选中的顶点才能拖拽
15925
+ if (platform === PlatformType.H5 && selectedVertexIndex !== index) {
15926
+ return;
15927
+ }
15886
15928
  e.preventDefault();
15887
15929
  e.stopPropagation();
15888
15930
  // 如果正在双击,忽略mouseDown事件
@@ -15909,7 +15951,7 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15909
15951
  });
15910
15952
  mouseDownTimerRef.current = null;
15911
15953
  }, 250);
15912
- }, [editMode, createMode, completed, coordinates, tooltipIndex]);
15954
+ }, [editMode, createMode, completed, coordinates, tooltipIndex, platform, selectedVertexIndex]);
15913
15955
  // 点击边线创建新顶点
15914
15956
  const handleEdgeClick = useCallback((e, edgeStartIndex) => {
15915
15957
  // 只有在编辑模式或者创建模式已完成时才能点击边线创建新顶点
@@ -15944,6 +15986,8 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15944
15986
  edgeInfo: edgeInfo,
15945
15987
  dragType: 'new',
15946
15988
  });
15989
+ // 将新创建的点设为选中态,便于后续直接拖拽
15990
+ setSelectedVertexIndex(insertIndex);
15947
15991
  }, [
15948
15992
  editMode,
15949
15993
  createMode,
@@ -15953,6 +15997,69 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15953
15997
  getSVGCoordinates,
15954
15998
  calculatePerpendicularFoot$1,
15955
15999
  ]);
16000
+ // H5平台长按边线创建新顶点
16001
+ const handleEdgeLongPressStart = useCallback((e, edgeStartIndex) => {
16002
+ if ((!editMode && !(createMode && completed)) || dragState.isDragging)
16003
+ return;
16004
+ e.preventDefault();
16005
+ e.stopPropagation();
16006
+ const clickCoords = getSVGCoordinates(e.clientX, e.clientY);
16007
+ longPressStartPosRef.current = clickCoords;
16008
+ longPressEdgeIndexRef.current = edgeStartIndex;
16009
+ // 开始长按计时器(500ms)
16010
+ longPressTimerRef.current = window.setTimeout(() => {
16011
+ isLongPressedRef.current = true;
16012
+ // 长按触发,创建新顶点
16013
+ if (longPressEdgeIndexRef.current !== -1 && longPressStartPosRef.current) {
16014
+ handleEdgeClick(e, longPressEdgeIndexRef.current);
16015
+ }
16016
+ }, 500);
16017
+ }, [editMode, createMode, completed, dragState.isDragging, getSVGCoordinates, handleEdgeClick]);
16018
+ // 长按结束或取消
16019
+ const handleEdgeLongPressEnd = useCallback(() => {
16020
+ if (longPressTimerRef.current !== null) {
16021
+ window.clearTimeout(longPressTimerRef.current);
16022
+ longPressTimerRef.current = null;
16023
+ }
16024
+ isLongPressedRef.current = false;
16025
+ longPressStartPosRef.current = null;
16026
+ longPressEdgeIndexRef.current = -1;
16027
+ }, []);
16028
+ // H5平台长按顶点选中
16029
+ const vertexLongPressTimerRef = useRef(null);
16030
+ const isVertexLongPressedRef = useRef(false);
16031
+ const longPressVertexIndexRef = useRef(-1);
16032
+ // 长按拖拽判定相关
16033
+ const touchStartPosRef = useRef(null);
16034
+ const hasStartedDragViaLongPressRef = useRef(false);
16035
+ const DRAG_START_THRESHOLD = 8; // 像素阈值,超过则认为进入拖拽
16036
+ // H5平台双击检测
16037
+ const lastTapRef = useRef(0);
16038
+ const lastTapIndexRef = useRef(-1);
16039
+ const DOUBLE_TAP_DELAY = 300; // 双击检测间隔时间(ms)
16040
+ const handleVertexLongPressStart = useCallback((e, index) => {
16041
+ if ((!editMode && !(createMode && completed)) || dragState.isDragging)
16042
+ return;
16043
+ e.preventDefault();
16044
+ e.stopPropagation();
16045
+ longPressVertexIndexRef.current = index;
16046
+ hasStartedDragViaLongPressRef.current = false;
16047
+ touchStartPosRef.current = { x: e.clientX, y: e.clientY };
16048
+ // 开始长按计时器(1000ms)
16049
+ vertexLongPressTimerRef.current = window.setTimeout(() => {
16050
+ isVertexLongPressedRef.current = true;
16051
+ setSelectedVertexIndex(index);
16052
+ }, 1000);
16053
+ }, [editMode, createMode, completed, dragState.isDragging]);
16054
+ const handleVertexLongPressEnd = useCallback(() => {
16055
+ if (vertexLongPressTimerRef.current !== null) {
16056
+ window.clearTimeout(vertexLongPressTimerRef.current);
16057
+ vertexLongPressTimerRef.current = null;
16058
+ }
16059
+ isVertexLongPressedRef.current = false;
16060
+ longPressVertexIndexRef.current = -1;
16061
+ touchStartPosRef.current = null;
16062
+ }, []);
15956
16063
  const showNotCreateCursor = useMemo(() => {
15957
16064
  if (!dragState?.isDragging || !dragState?.currentPosition)
15958
16065
  return false;
@@ -15982,6 +16089,11 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15982
16089
  const clickTimerRef = useRef(null);
15983
16090
  const mouseDownTimerRef = useRef(null);
15984
16091
  const isDoubleClickingRef = useRef(false);
16092
+ // 长按事件相关
16093
+ const longPressTimerRef = useRef(null);
16094
+ const isLongPressedRef = useRef(false);
16095
+ const longPressStartPosRef = useRef(null);
16096
+ const longPressEdgeIndexRef = useRef(-1);
15985
16097
  // 清理 requestAnimationFrame 和事件定时器
15986
16098
  useEffect(() => {
15987
16099
  return () => {
@@ -15997,6 +16109,14 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
15997
16109
  window.clearTimeout(mouseDownTimerRef.current);
15998
16110
  mouseDownTimerRef.current = null;
15999
16111
  }
16112
+ if (longPressTimerRef.current !== null) {
16113
+ window.clearTimeout(longPressTimerRef.current);
16114
+ longPressTimerRef.current = null;
16115
+ }
16116
+ if (vertexLongPressTimerRef.current !== null) {
16117
+ window.clearTimeout(vertexLongPressTimerRef.current);
16118
+ vertexLongPressTimerRef.current = null;
16119
+ }
16000
16120
  };
16001
16121
  }, []);
16002
16122
  // 拖拽过程中更新坐标 - 使用节流优化性能
@@ -16024,6 +16144,40 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16024
16144
  });
16025
16145
  }
16026
16146
  }, [dragState.isDragging, dragState.dragIndex, getSVGCoordinates]);
16147
+ // 处理 H5 顶点长按后的触摸移动以进入拖拽
16148
+ const handleVertexTouchMoveMaybeStartDrag = useCallback((e, idx) => {
16149
+ if (platform !== PlatformType.H5)
16150
+ return;
16151
+ if (dragState.isDragging)
16152
+ return; // 已在拖拽
16153
+ // 允许两种进入拖拽的途径:
16154
+ // 1) 长按该点
16155
+ // 2) 该点已处于选中态
16156
+ const canDragNow = isVertexLongPressedRef.current && longPressVertexIndexRef.current === idx;
16157
+ const canDragBecauseSelected = selectedVertexIndex === idx;
16158
+ if (!canDragNow && !canDragBecauseSelected)
16159
+ return;
16160
+ if (touchStartPosRef.current) {
16161
+ const dx = e.clientX - touchStartPosRef.current.x;
16162
+ const dy = e.clientY - touchStartPosRef.current.y;
16163
+ const dist = Math.sqrt(dx * dx + dy * dy);
16164
+ if (dist >= DRAG_START_THRESHOLD) {
16165
+ // 进入拖拽状态
16166
+ const index = idx;
16167
+ hasStartedDragViaLongPressRef.current = true;
16168
+ // 启动与 mouseDown 相同的拖拽逻辑
16169
+ setDragState({
16170
+ isDragging: true,
16171
+ dragIndex: index,
16172
+ originalPosition: [...coordinates[index]],
16173
+ currentPosition: [...coordinates[index]],
16174
+ newVertexIndex: -1,
16175
+ edgeInfo: null,
16176
+ dragType: 'existing',
16177
+ });
16178
+ }
16179
+ }
16180
+ }, [platform, dragState.isDragging, coordinates, selectedVertexIndex]);
16027
16181
  // 结束拖拽
16028
16182
  const handleMouseUp = useCallback(() => {
16029
16183
  console.log('handleMouseUp', JSON.stringify(dragState));
@@ -16079,9 +16233,12 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16079
16233
  },
16080
16234
  }, platform);
16081
16235
  document.body.style.userSelect = 'none';
16236
+ // 禁止系统滚动和浏览器触摸手势,防止底层地图跟随移动
16237
+ document.body.style.touchAction = 'none';
16082
16238
  return () => {
16083
16239
  cleanup();
16084
16240
  document.body.style.userSelect = '';
16241
+ document.body.style.touchAction = '';
16085
16242
  };
16086
16243
  }
16087
16244
  else {
@@ -16146,6 +16303,45 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16146
16303
  const ghostFirstMidpoint = createMode && mousePos && !completed && renderCoordinates.length >= 1
16147
16304
  ? calculateMidpoint(renderCoordinates[0], [mousePos.x, mousePos.y])
16148
16305
  : null;
16306
+ // H5平台处理触摸双击
16307
+ const handleVertexDoubleTap = useCallback((index) => {
16308
+ const now = Date.now();
16309
+ const timeDelta = now - lastTapRef.current;
16310
+ // 检查是否为双击(300ms内,且是同一个点)
16311
+ if (timeDelta < DOUBLE_TAP_DELAY && lastTapIndexRef.current === index) {
16312
+ // 只有在选中点的情况下才允许删除
16313
+ if (selectedVertexIndex === index && onVertexDelete && coordinates.length > 3) {
16314
+ // 将渲染索引转换为原始points的索引
16315
+ onVertexDelete(renderCoordinates?.length - 1 - index);
16316
+ // 删除后立即取消拖拽状态,避免误触发拖动
16317
+ setDragState({
16318
+ isDragging: false,
16319
+ dragIndex: -1,
16320
+ originalPosition: null,
16321
+ currentPosition: null,
16322
+ newVertexIndex: -1,
16323
+ edgeInfo: null,
16324
+ dragType: null,
16325
+ });
16326
+ // 删除后取消选中状态
16327
+ setSelectedVertexIndex(-1);
16328
+ }
16329
+ // 重置点击时间
16330
+ lastTapRef.current = 0;
16331
+ lastTapIndexRef.current = -1;
16332
+ }
16333
+ else {
16334
+ // 记录本次点击
16335
+ lastTapRef.current = now;
16336
+ lastTapIndexRef.current = index;
16337
+ }
16338
+ }, [
16339
+ selectedVertexIndex,
16340
+ onVertexDelete,
16341
+ coordinates?.length,
16342
+ editMapInfo?.createMode,
16343
+ renderCoordinates?.length,
16344
+ ]);
16149
16345
  return (jsxs(Fragment, { children: [(editMode || (createMode && completed)) &&
16150
16346
  dragState.isDragging &&
16151
16347
  dragState.dragType !== 'new' &&
@@ -16172,9 +16368,16 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16172
16368
  renderCoordinates.map((coord, index) => {
16173
16369
  const nextCoord = renderCoordinates[(index + 1) % renderCoordinates.length];
16174
16370
  const isDashPath = coord[2] === 1;
16175
- return (jsx("line", { x1: coord[0], y1: coord[1], x2: nextCoord[0], y2: nextCoord[1], stroke: isDashPath ? 'transparent' : strokeColor, strokeWidth: strokeWidth, className: styles$2.addVertex, vectorEffect: "non-scaling-stroke", ...(platform === PlatformType.H5
16371
+ return (jsx("line", { x1: coord[0], y1: coord[1], x2: nextCoord[0], y2: nextCoord[1], stroke: isDashPath ? 'transparent' : strokeColor, strokeWidth: platform === PlatformType.H5 ? strokeWidth * 3 : strokeWidth, className: styles$2.addVertex, style: {
16372
+ userSelect: 'none',
16373
+ WebkitUserSelect: 'none',
16374
+ WebkitTouchCallout: 'none',
16375
+ touchAction: 'none',
16376
+ }, vectorEffect: "non-scaling-stroke", ...(platform === PlatformType.H5
16176
16377
  ? {
16177
- onTouchStart: createReactEventHandler((e) => handleEdgeClick(e, index)),
16378
+ onTouchStart: createReactEventHandler((e) => handleEdgeLongPressStart(e, index)),
16379
+ onTouchEnd: createReactEventHandler(() => handleEdgeLongPressEnd()),
16380
+ onTouchCancel: createReactEventHandler(() => handleEdgeLongPressEnd()),
16178
16381
  }
16179
16382
  : {
16180
16383
  onMouseDown: (e) => handleEdgeClick(e, index),
@@ -16197,14 +16400,27 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16197
16400
  setHoverVertex(null);
16198
16401
  },
16199
16402
  }) }, `edge-${index}`));
16200
- }), ghostLastPath && (jsx("path", { d: ghostLastPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), ghostFirstPath && renderCoordinates.length >= 2 && (jsx("path", { d: ghostFirstPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), jsx(DragDistanceIndicator, { dragState: dragState, strokeColor: strokeColor, editMode: editMode, createMode: createMode, completed: completed, fontSize: 30 * overlayScale }), jsx(DistanceLabels, { coordinates: renderCoordinates, createMode: createMode, editMode: editMode, completed: completed, showPoints: showPoints, mousePos: mousePos, ghostLastDistance: ghostLastDistance, ghostLastMidpoint: ghostLastMidpoint, ghostFirstDistance: ghostFirstDistance, ghostFirstMidpoint: ghostFirstMidpoint, fontSize: 30 * overlayScale }), hoverVertex && !dragState.isDragging && (jsx(VertexElement, { cx: hoverVertex.position.x, cy: hoverVertex.position.y, stroke: strokeColor, strokeOpacity: 0.6, fill: "white", fillOpacity: 0.8, pointerEvents: "none" })), ((createMode && showPoints) || editMode || (createMode && completed)) &&
16403
+ }), ghostLastPath && (jsx("path", { d: ghostLastPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), ghostFirstPath && renderCoordinates.length >= 2 && (jsx("path", { d: ghostFirstPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), jsx(DragDistanceIndicator, { dragState: dragState, strokeColor: strokeColor, editMode: editMode, createMode: createMode, completed: completed, fontSize: platform === PlatformType.H5 ? 12 * overlayScale : 30 * overlayScale }), jsx(DistanceLabels, { coordinates: renderCoordinates, createMode: createMode, editMode: editMode, completed: completed, showPoints: showPoints, mousePos: mousePos, ghostLastDistance: ghostLastDistance, ghostLastMidpoint: ghostLastMidpoint, ghostFirstDistance: ghostFirstDistance, ghostFirstMidpoint: ghostFirstMidpoint, fontSize: platform === PlatformType.H5 ? 12 * overlayScale : 30 * overlayScale }), hoverVertex && !dragState.isDragging && (jsx(VertexElement, { cx: hoverVertex.position.x, cy: hoverVertex.position.y, stroke: strokeColor, strokeOpacity: 0.6, fill: "white", fillOpacity: 0.8, pointerEvents: "none" })), ((createMode && showPoints) || editMode || (createMode && completed)) &&
16201
16404
  renderCoordinates.map((coord, idx) => {
16202
16405
  // 判断当前顶点的状态
16203
16406
  const isLastPoint = idx === renderCoordinates.length - 1;
16204
16407
  const canComplete = createMode && !completed && renderCoordinates.length >= 3 && isLastPoint;
16205
16408
  const isCreatedAndCanDrag = createMode && completed; // 创建完成后可拖拽
16206
16409
  const isInEditMode = editMode;
16207
- return (jsxs("g", { children: [jsx(VertexElement, { className: generateVertexClassName, stroke: strokeColor, cx: coord[0], cy: coord[1], r: canComplete ? 16 : 12, onClick: (e) => handleVertexClick(e, idx), onDoubleClick: (e) => {
16410
+ // H5模式下选中的顶点显示蓝色,并且放大1.5倍
16411
+ const isSelected = platform === PlatformType.H5 && selectedVertexIndex === idx;
16412
+ const vertexRadius = isSelected ? (canComplete ? 16 : 12) * 1.2 : canComplete ? 16 : 12;
16413
+ const vertexFill = isSelected ? '#FFAB7E' : 'white';
16414
+ return (jsxs("g", { children: [jsx(VertexElement, { className: generateVertexClassName, style: {
16415
+ userSelect: 'none',
16416
+ WebkitUserSelect: 'none',
16417
+ WebkitTouchCallout: 'none',
16418
+ touchAction: 'none',
16419
+ }, stroke: strokeColor, fill: vertexFill, cx: coord[0], cy: coord[1], r: vertexRadius, onClick: (e) => handleVertexClick(e, idx), onDoubleClick: (e) => {
16420
+ console.log('双击事件', selectedVertexIndex, idx);
16421
+ if (platform === PlatformType.H5) {
16422
+ return;
16423
+ }
16208
16424
  // 阻止双击事件冒泡到Google Maps
16209
16425
  e.preventDefault();
16210
16426
  e.stopPropagation();
@@ -16222,12 +16438,6 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16222
16438
  setTimeout(() => {
16223
16439
  isDoubleClickingRef.current = false;
16224
16440
  }, 300);
16225
- if (platform === PlatformType.H5) {
16226
- if (onVertexDelete && coordinates.length > 3) {
16227
- onVertexDelete(idx);
16228
- }
16229
- return;
16230
- }
16231
16441
  // 打开删除确认 Tooltip(仅在可编辑时)
16232
16442
  if (editMode || (createMode && completed)) {
16233
16443
  setTooltipIndex(idx);
@@ -16235,12 +16445,51 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
16235
16445
  }, ...(platform === PlatformType.H5
16236
16446
  ? {
16237
16447
  onTouchStart: createReactEventHandler((e) => {
16238
- // 拖拽逻辑:编辑模式或创建完成后
16239
- if (isInEditMode || isCreatedAndCanDrag) {
16240
- if (draggable) {
16241
- handleVertexMouseDown(e, idx);
16242
- }
16448
+ e.preventDefault();
16449
+ e.stopPropagation();
16450
+ // 如果不是支持拖拽的话,则不往下走
16451
+ if (!draggable) {
16452
+ return;
16453
+ }
16454
+ // 如果未选中,则走长按选中逻辑
16455
+ if (selectedVertexIndex !== idx) {
16456
+ handleVertexLongPressStart(e, idx);
16243
16457
  }
16458
+ else {
16459
+ // 已选中:准备可能的拖拽(记录起点),不阻塞双击
16460
+ touchStartPosRef.current = {
16461
+ x: e.clientX,
16462
+ y: e.clientY,
16463
+ };
16464
+ hasStartedDragViaLongPressRef.current = false;
16465
+ isVertexLongPressedRef.current = false;
16466
+ longPressVertexIndexRef.current = idx;
16467
+ }
16468
+ }),
16469
+ onTouchMove: createReactEventHandler((e) => {
16470
+ // 如果不是支持拖拽的话,则不往下走
16471
+ if (!draggable) {
16472
+ return;
16473
+ }
16474
+ // 长按后,超过阈值再进入拖拽
16475
+ handleVertexTouchMoveMaybeStartDrag(e, idx);
16476
+ }),
16477
+ onTouchEnd: createReactEventHandler(() => {
16478
+ // 如果不是支持拖拽的话,则不往下走
16479
+ if (!draggable) {
16480
+ return;
16481
+ }
16482
+ // 如果已经通过长按进入拖拽,不触发双击检测
16483
+ const startedDrag = hasStartedDragViaLongPressRef.current;
16484
+ handleVertexLongPressEnd();
16485
+ if (!startedDrag && !isVertexLongPressedRef.current) {
16486
+ handleVertexDoubleTap(idx);
16487
+ }
16488
+ hasStartedDragViaLongPressRef.current = false;
16489
+ }),
16490
+ onTouchCancel: createReactEventHandler(() => {
16491
+ handleVertexLongPressEnd();
16492
+ hasStartedDragViaLongPressRef.current = false;
16244
16493
  }),
16245
16494
  }
16246
16495
  : {
@@ -16320,12 +16569,19 @@ const BoundaryElement = ({ data }) => {
16320
16569
  editMapInfo.mobileMode === MobileEditMode.CREATE) {
16321
16570
  return;
16322
16571
  }
16323
- setEditMapInfo((prev) => ({
16324
- ...prev,
16325
- mobileMode: MobileEditMode.START,
16326
- elementType: DataType.BOUNDARY,
16327
- selectElement: data,
16328
- }));
16572
+ if (editMapInfo.selectElement?.id === data.id) {
16573
+ setEditMapInfo({
16574
+ ...INIT_EDIT_MAP_INFO,
16575
+ });
16576
+ }
16577
+ else {
16578
+ setEditMapInfo((prev) => ({
16579
+ ...prev,
16580
+ mobileMode: MobileEditMode.START,
16581
+ elementType: DataType.BOUNDARY,
16582
+ selectElement: data,
16583
+ }));
16584
+ }
16329
16585
  }
16330
16586
  else {
16331
16587
  if (editMapInfo?.selectElement)
@@ -16338,7 +16594,11 @@ const BoundaryElement = ({ data }) => {
16338
16594
  }));
16339
16595
  }
16340
16596
  }, [platform, data, editMapInfo]);
16341
- return (jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: onPathClick, onCoordinatesChange: (coordinates) => {
16597
+ return (jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: onPathClick, onPolygonClick: () => {
16598
+ if (platform === PlatformType.H5) {
16599
+ onPathClick();
16600
+ }
16601
+ }, onCoordinatesChange: (coordinates) => {
16342
16602
  console.log('onCoordinatesChange', coordinates);
16343
16603
  setEditMapInfo((prev) => ({
16344
16604
  ...prev,
@@ -16460,25 +16720,26 @@ const ObstacleElement = ({ data }) => {
16460
16720
  const { addHistory } = useHistoryHandle();
16461
16721
  // 处理删除顶点
16462
16722
  const handleCreateVertexDelete = useCallback((vertexIndex) => {
16723
+ console.log('ObstacleElement删除顶点', vertexIndex);
16463
16724
  if (editMapInfo?.selectElement?.points && editMapInfo?.selectElement?.points?.length > 0) {
16464
16725
  const newPoints = editMapInfo?.selectElement?.points?.filter((_, index) => index !== vertexIndex);
16726
+ console.log('newPoints', newPoints);
16465
16727
  setEditMapInfo((prev) => ({
16466
16728
  ...prev,
16467
16729
  selectElement: {
16468
16730
  ...prev.selectElement,
16469
- points: newPoints,
16731
+ points: [...newPoints],
16470
16732
  },
16471
16733
  }));
16472
16734
  addHistory({
16473
16735
  selectElement: {
16474
16736
  ...editMapInfo.selectElement,
16475
- points: newPoints,
16737
+ points: [...newPoints],
16476
16738
  },
16477
16739
  });
16478
16740
  }
16479
16741
  }, [editMapInfo]);
16480
16742
  const currentPoints = useMemo(() => {
16481
- // 为了方便解决删除顶点的时候,delete icon被遮挡的问题,所以逆序一下
16482
16743
  if (editMapInfo?.selectElement?.id === data.id) {
16483
16744
  return editMapInfo.selectElement.points;
16484
16745
  }
@@ -16504,13 +16765,19 @@ const ObstacleElement = ({ data }) => {
16504
16765
  editMapInfo.mobileMode === MobileEditMode.CREATE) {
16505
16766
  return;
16506
16767
  }
16507
- setEditMapInfo((prev) => ({
16508
- ...prev,
16509
- mobileMode: MobileEditMode.START,
16510
- elementType: DataType.OBSTACLE,
16511
- selectElement: data,
16512
- }));
16513
- return;
16768
+ if (editMapInfo.selectElement?.id === data.id) {
16769
+ setEditMapInfo({
16770
+ ...INIT_EDIT_MAP_INFO,
16771
+ });
16772
+ }
16773
+ else {
16774
+ setEditMapInfo((prev) => ({
16775
+ ...prev,
16776
+ mobileMode: MobileEditMode.START,
16777
+ elementType: DataType.OBSTACLE,
16778
+ selectElement: data,
16779
+ }));
16780
+ }
16514
16781
  }
16515
16782
  if (disabledObstacles || editMapInfo?.selectElement)
16516
16783
  return;
@@ -16541,10 +16808,12 @@ const ObstacleElement = ({ data }) => {
16541
16808
  return editMapInfo?.selectElement?.id === data.id;
16542
16809
  }, [editMapInfo, data, platform]);
16543
16810
  return (jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: editMode, showPoints: editMapInfo?.selectElement?.id === data.id, onPathClick: onPathClick, onPolygonClick: () => {
16811
+ // h5的情况下,支持点击禁区内部,也会触发选中
16544
16812
  if (platform === PlatformType.H5) {
16545
16813
  onPathClick();
16546
16814
  }
16547
16815
  }, onVertexDelete: (vertexIndex) => handleCreateVertexDelete(vertexIndex), onCoordinatesChange: (coordinates) => {
16816
+ console.log('onCoordinatesChange', coordinates);
16548
16817
  if (platform === PlatformType.H5 && editMapInfo.mobileMode === MobileEditMode.CREATE) {
16549
16818
  return;
16550
16819
  }
@@ -17348,15 +17617,12 @@ const VisionOffElement = ({ data, onSelect }) => {
17348
17617
  if (platform === PlatformType.H5) {
17349
17618
  // h5编辑模式下,
17350
17619
  // start模式可以任意选
17351
- // create或者是edit模式的话,只有选中的是visionOff的时候才能选中
17352
- if ((editMapInfo.mobileMode === MobileEditMode.CREATE ||
17353
- editMapInfo.mobileMode === MobileEditMode.EDIT) &&
17354
- editMapInfo.elementType !== DataType.VISION_OFF) {
17355
- return;
17356
- }
17357
- if ((editMapInfo.mobileMode === MobileEditMode.CREATE ||
17358
- editMapInfo.mobileMode === MobileEditMode.EDIT) &&
17359
- editMapInfo.elementType === DataType.VISION_OFF) {
17620
+ // create或者是edit模式的话,只有选中的是visionOff的时候才能操作
17621
+ if (editMapInfo.mobileMode === MobileEditMode.CREATE ||
17622
+ editMapInfo.mobileMode === MobileEditMode.EDIT) {
17623
+ if (editMapInfo.elementType !== DataType.VISION_OFF) {
17624
+ return;
17625
+ }
17360
17626
  setEditMapInfo((prev) => ({
17361
17627
  ...prev,
17362
17628
  selectElement: data,
@@ -17365,12 +17631,19 @@ const VisionOffElement = ({ data, onSelect }) => {
17365
17631
  }));
17366
17632
  return;
17367
17633
  }
17368
- setEditMapInfo((prev) => ({
17369
- ...prev,
17370
- selectElement: data,
17371
- elementType: DataType.VISION_OFF,
17372
- mobileMode: MobileEditMode.START,
17373
- }));
17634
+ if (editMapInfo.selectElement?.id === data.id) {
17635
+ setEditMapInfo({
17636
+ ...INIT_EDIT_MAP_INFO,
17637
+ });
17638
+ }
17639
+ else {
17640
+ setEditMapInfo((prev) => ({
17641
+ ...prev,
17642
+ selectElement: data,
17643
+ elementType: DataType.VISION_OFF,
17644
+ mobileMode: MobileEditMode.START,
17645
+ }));
17646
+ }
17374
17647
  return;
17375
17648
  }
17376
17649
  if (editMapInfo?.selectElement)
@@ -17882,7 +18155,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
17882
18155
  }, [data]);
17883
18156
  const remainingTime = useMemo(() => {
17884
18157
  const currentTime = Math.floor(Date.now() / 1000);
17885
- console.log('data.expiration_ts--', data.expiration_ts);
18158
+ // console.log('data.expiration_ts--', data.expiration_ts);
17886
18159
  if (data.expiration_ts <= currentTime) {
17887
18160
  return 0;
17888
18161
  }
@@ -18183,7 +18456,7 @@ const DoodleElement = ({ data }) => {
18183
18456
  editMapInfo.mobileMode === MobileEditMode.EDIT) {
18184
18457
  return;
18185
18458
  }
18186
- // 如果是编辑的话
18459
+ // 如果start模式下
18187
18460
  setEditMapInfo((prev) => ({
18188
18461
  ...prev,
18189
18462
  selectElement: data,
@@ -19313,7 +19586,7 @@ function usePolygonDrawing(options = {}) {
19313
19586
  const { checkCanNotCreateAtPosition } = useCheckElement();
19314
19587
  const { addHistory } = useHistoryHandle();
19315
19588
  const points = useMemo(() => {
19316
- console.log('points->', editMapInfo?.selectElement?.points);
19589
+ // console.log('points->', editMapInfo?.selectElement?.points);
19317
19590
  return editMapInfo?.selectElement?.points?.map((item) => ({ x: item[0], y: item[1] })) || [];
19318
19591
  }, [editMapInfo?.selectElement?.points]);
19319
19592
  const completed = useMemo(() => {
@@ -20457,13 +20730,6 @@ modelType, mapRef, mapJson, pathJson, realTimeData, antennaConfig, onMapLoad, on
20457
20730
  const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
20458
20731
  console.log('scale', scale, currentZoom, zoomDiff);
20459
20732
  setOverlayScale(scale < 1 ? 1 : scale);
20460
- // if (scale < 1) {
20461
- // setOverlayScale(1);
20462
- // } else if (scale > 4) {
20463
- // setOverlayScale(4);
20464
- // } else {
20465
- // setOverlayScale(scale);
20466
- // }
20467
20733
  };
20468
20734
  // 使用lodash throttle进行节流处理: 100ms内只执行一次
20469
20735
  const handleZoomChanged = throttle$2(updateScale, 50);