@fleet-frontend/mower-maps 0.2.0-beta.12 → 0.2.0-beta.14
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/context/mapEdit.d.ts +1 -1
- package/dist/context/mapEdit.d.ts.map +1 -1
- package/dist/index.esm.js +399 -152
- package/dist/index.js +399 -152
- package/dist/render/MowerMapRenderer.d.ts.map +1 -1
- package/dist/render/svgEditMap/hooks/useCheckElement.d.ts.map +1 -1
- package/dist/render/svgElement/BoundaryElement/index.d.ts.map +1 -1
- package/dist/render/svgElement/DoodleElement/index.d.ts.map +1 -1
- package/dist/render/svgElement/ObstacleElement/index.d.ts.map +1 -1
- package/dist/render/svgElement/PolygonELement/components/DistanceLabels.d.ts +1 -0
- package/dist/render/svgElement/PolygonELement/components/DistanceLabels.d.ts.map +1 -1
- package/dist/render/svgElement/PolygonELement/index.d.ts.map +1 -1
- package/dist/render/svgElement/PolygonELement/vertex/index.d.ts +1 -1
- package/dist/render/svgElement/PolygonELement/vertex/index.d.ts.map +1 -1
- package/dist/render/svgElement/TextElement/index.d.ts.map +1 -1
- package/dist/render/svgElement/TransformWrapper/VisionOffTransformWrapper/VisionOffTransformWrapper.d.ts.map +1 -1
- package/dist/render/svgElement/VisionOffElement/index.d.ts.map +1 -1
- package/package.json +1 -1
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: '
|
|
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
|
};
|
|
@@ -15212,10 +15213,10 @@ const calculatePhysicalDistance$1 = (point1, point2) => {
|
|
|
15212
15213
|
const calculateMidpoint$1 = (point1, point2) => {
|
|
15213
15214
|
return [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2];
|
|
15214
15215
|
};
|
|
15215
|
-
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
|
+
const DistanceLabels = ({ coordinates, createMode = false, editMode = false, completed = false, showPoints = false, mousePos: _mousePos = null, ghostLastDistance = null, ghostLastMidpoint = null, ghostFirstDistance = null, ghostFirstMidpoint = null, fontSize = 30, showFirstDistance = true, }) => {
|
|
15216
15217
|
// 只在显示可操作顶点时显示距离
|
|
15217
15218
|
if (!((createMode && showPoints) || editMode || (createMode && completed)) ||
|
|
15218
|
-
coordinates.length < 1) {
|
|
15219
|
+
coordinates.length < (showFirstDistance ? 1 : 2)) {
|
|
15219
15220
|
return null;
|
|
15220
15221
|
}
|
|
15221
15222
|
return (jsxs(Fragment, { children: [coordinates.map((coord, idx) => {
|
|
@@ -15227,14 +15228,32 @@ const DistanceLabels = ({ coordinates, createMode = false, editMode = false, com
|
|
|
15227
15228
|
}
|
|
15228
15229
|
const midpoint = calculateMidpoint$1(coord, nextCoord);
|
|
15229
15230
|
const distance = calculatePhysicalDistance$1(coord, nextCoord);
|
|
15231
|
+
// 如果当前点和下一个点坐标一致则不现实,处理头尾点一样的问题
|
|
15232
|
+
if (coord[0] === nextCoord[0] && coord[1] === nextCoord[1]) {
|
|
15233
|
+
return null;
|
|
15234
|
+
}
|
|
15230
15235
|
return (jsx(TextElement, { x: midpoint[0], y: midpoint[1], textAnchor: "middle", alignmentBaseline: "middle", fontSize: fontSize, fill: "#fff", style: {
|
|
15231
15236
|
pointerEvents: 'none',
|
|
15232
15237
|
fontWeight: 'bold',
|
|
15238
|
+
userSelect: 'none',
|
|
15239
|
+
WebkitUserSelect: 'none',
|
|
15240
|
+
WebkitTouchCallout: 'none',
|
|
15241
|
+
touchAction: 'none',
|
|
15233
15242
|
}, text: distance }, `distance-${idx}`));
|
|
15234
|
-
}), ghostLastDistance && ghostLastMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostLastMidpoint[0], y: ghostLastMidpoint[1], text: ghostLastDistance
|
|
15243
|
+
}), ghostLastDistance && ghostLastMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostLastMidpoint[0], y: ghostLastMidpoint[1], text: ghostLastDistance, style: {
|
|
15244
|
+
userSelect: 'none',
|
|
15245
|
+
WebkitUserSelect: 'none',
|
|
15246
|
+
WebkitTouchCallout: 'none',
|
|
15247
|
+
touchAction: 'none',
|
|
15248
|
+
} })), ghostFirstDistance && ghostFirstMidpoint && (jsx(TextElement, { fontSize: fontSize, x: ghostFirstMidpoint[0], y: ghostFirstMidpoint[1], text: ghostFirstDistance, style: {
|
|
15249
|
+
userSelect: 'none',
|
|
15250
|
+
WebkitUserSelect: 'none',
|
|
15251
|
+
WebkitTouchCallout: 'none',
|
|
15252
|
+
touchAction: 'none',
|
|
15253
|
+
} }))] }));
|
|
15235
15254
|
};
|
|
15236
15255
|
|
|
15237
|
-
var css_248z$2 = ".index-module_polygonPathG__S-Bpl {\n
|
|
15256
|
+
var css_248z$2 = ".index-module_polygonPathG__S-Bpl {\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}";
|
|
15238
15257
|
var styles$2 = {"polygonPathG":"index-module_polygonPathG__S-Bpl","vertex":"index-module_vertex__-Qb1u","dragging":"index-module_dragging__xSFdO","addVertex":"index-module_addVertex__hrF71","polygonPath":"index-module_polygonPath__PynOn","notCreate":"index-module_notCreate__bFnkV"};
|
|
15239
15258
|
styleInject(css_248z$2);
|
|
15240
15259
|
|
|
@@ -15527,6 +15546,7 @@ function coordinatesToPoints$1(coordinates) {
|
|
|
15527
15546
|
|
|
15528
15547
|
const useCheckElement = () => {
|
|
15529
15548
|
const { editMapInfo, minDistance } = useMapEditContext();
|
|
15549
|
+
const { platform } = useCommonContext();
|
|
15530
15550
|
const { svgElementDatas } = useSvgEditContext();
|
|
15531
15551
|
const checkDoodle = useCallback(() => {
|
|
15532
15552
|
console.log('checkdoodle', editMapInfo, svgElementDatas);
|
|
@@ -15627,7 +15647,7 @@ const useCheckElement = () => {
|
|
|
15627
15647
|
return { isValid: true };
|
|
15628
15648
|
}, [editMapInfo, svgElementDatas, minDistance]);
|
|
15629
15649
|
const checkCanNotCreateAtPosition = useCallback((checkPoint, checkPoints) => {
|
|
15630
|
-
console.log('editMapInfo.elementType--->', editMapInfo);
|
|
15650
|
+
// console.log('editMapInfo.elementType--->', editMapInfo);
|
|
15631
15651
|
if (!editMapInfo.elementType)
|
|
15632
15652
|
return false;
|
|
15633
15653
|
const currentPoints = editMapInfo?.selectElement?.points;
|
|
@@ -15654,8 +15674,10 @@ const useCheckElement = () => {
|
|
|
15654
15674
|
return false;
|
|
15655
15675
|
// 获取当前正在创建的 obstacle 的点
|
|
15656
15676
|
const currentObstaclePoints = coordinatesToPoints$1(points) || [];
|
|
15657
|
-
if (
|
|
15658
|
-
|
|
15677
|
+
if (platform !== PlatformType.H5) {
|
|
15678
|
+
if (currentObstaclePoints.length === 0)
|
|
15679
|
+
return false; // 还没有开始绘制
|
|
15680
|
+
}
|
|
15659
15681
|
// 构建当前 obstacle 的多边形(包括检查点位置)
|
|
15660
15682
|
const currentObstaclePolygon = [...currentObstaclePoints, checkPoint];
|
|
15661
15683
|
// 获取当前边界内的所有元素
|
|
@@ -15811,12 +15833,21 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15811
15833
|
});
|
|
15812
15834
|
// 虚拟顶点hover状态
|
|
15813
15835
|
const [hoverVertex, setHoverVertex] = useState(null);
|
|
15836
|
+
// H5平台选中的顶点索引(长按后选中)
|
|
15837
|
+
const [selectedVertexIndex, setSelectedVertexIndex] = useState(-1);
|
|
15814
15838
|
const { checkCanNotCreateAtPosition } = useCheckElement();
|
|
15815
15839
|
const { editMapInfo } = useMapEditContext();
|
|
15816
15840
|
const { platform } = useCommonContext();
|
|
15817
15841
|
// delete icon可能被上一个点遮挡,因为delete在右上方,所以手动处理点让点按照顺时针渲染,这样delete icon层级就会高一些
|
|
15842
|
+
// 禁区的点最后一个和第一个相同,会导致一个位置渲染两个点,需要额外处理下
|
|
15818
15843
|
const coordinates = useMemo(() => {
|
|
15819
|
-
|
|
15844
|
+
const temp = editMapInfo?.createMode === CreateStatus.CREATING ? points : [...points].reverse();
|
|
15845
|
+
const firstPoint = temp[0] || [];
|
|
15846
|
+
const lastPoint = temp[temp.length - 1] || [];
|
|
15847
|
+
if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
|
|
15848
|
+
return temp.slice(0, -1);
|
|
15849
|
+
}
|
|
15850
|
+
return temp;
|
|
15820
15851
|
}, [points, editMapInfo?.createMode]);
|
|
15821
15852
|
// 计算点到线段的垂足坐标(使用通用工具函数)
|
|
15822
15853
|
const calculatePerpendicularFoot$1 = useCallback((point, lineStart, lineEnd) => {
|
|
@@ -15878,11 +15909,33 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15878
15909
|
if (tooltipIndex !== null)
|
|
15879
15910
|
setTooltipIndex(null);
|
|
15880
15911
|
}, [editMode, createMode, completed]);
|
|
15912
|
+
// H5平台:点击空白处取消选中状态
|
|
15913
|
+
useEffect(() => {
|
|
15914
|
+
if (platform !== PlatformType.H5 || selectedVertexIndex === -1)
|
|
15915
|
+
return;
|
|
15916
|
+
const handleDocumentClick = (e) => {
|
|
15917
|
+
// 检查点击的目标是否是顶点
|
|
15918
|
+
const target = e.target;
|
|
15919
|
+
const isClickingVertex = target.closest('circle') !== null;
|
|
15920
|
+
// 如果点击的不是顶点,则取消选中状态
|
|
15921
|
+
if (!isClickingVertex) {
|
|
15922
|
+
setSelectedVertexIndex(-1);
|
|
15923
|
+
}
|
|
15924
|
+
};
|
|
15925
|
+
document.addEventListener('click', handleDocumentClick);
|
|
15926
|
+
return () => {
|
|
15927
|
+
document.removeEventListener('click', handleDocumentClick);
|
|
15928
|
+
};
|
|
15929
|
+
}, [platform, selectedVertexIndex]);
|
|
15881
15930
|
// 处理顶点拖拽
|
|
15882
15931
|
const handleVertexMouseDown = useCallback((e, index) => {
|
|
15883
15932
|
// 只有在编辑模式或者创建模式已完成时才能拖拽
|
|
15884
15933
|
if (!editMode && !(createMode && completed))
|
|
15885
15934
|
return;
|
|
15935
|
+
// H5模式下,只有选中的顶点才能拖拽
|
|
15936
|
+
if (platform === PlatformType.H5 && selectedVertexIndex !== index) {
|
|
15937
|
+
return;
|
|
15938
|
+
}
|
|
15886
15939
|
e.preventDefault();
|
|
15887
15940
|
e.stopPropagation();
|
|
15888
15941
|
// 如果正在双击,忽略mouseDown事件
|
|
@@ -15909,7 +15962,7 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15909
15962
|
});
|
|
15910
15963
|
mouseDownTimerRef.current = null;
|
|
15911
15964
|
}, 250);
|
|
15912
|
-
}, [editMode, createMode, completed, coordinates, tooltipIndex]);
|
|
15965
|
+
}, [editMode, createMode, completed, coordinates, tooltipIndex, platform, selectedVertexIndex]);
|
|
15913
15966
|
// 点击边线创建新顶点
|
|
15914
15967
|
const handleEdgeClick = useCallback((e, edgeStartIndex) => {
|
|
15915
15968
|
// 只有在编辑模式或者创建模式已完成时才能点击边线创建新顶点
|
|
@@ -15944,6 +15997,8 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15944
15997
|
edgeInfo: edgeInfo,
|
|
15945
15998
|
dragType: 'new',
|
|
15946
15999
|
});
|
|
16000
|
+
// 将新创建的点设为选中态,便于后续直接拖拽
|
|
16001
|
+
setSelectedVertexIndex(insertIndex);
|
|
15947
16002
|
}, [
|
|
15948
16003
|
editMode,
|
|
15949
16004
|
createMode,
|
|
@@ -15953,6 +16008,69 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15953
16008
|
getSVGCoordinates,
|
|
15954
16009
|
calculatePerpendicularFoot$1,
|
|
15955
16010
|
]);
|
|
16011
|
+
// H5平台长按边线创建新顶点
|
|
16012
|
+
const handleEdgeLongPressStart = useCallback((e, edgeStartIndex) => {
|
|
16013
|
+
if ((!editMode && !(createMode && completed)) || dragState.isDragging)
|
|
16014
|
+
return;
|
|
16015
|
+
e.preventDefault();
|
|
16016
|
+
e.stopPropagation();
|
|
16017
|
+
const clickCoords = getSVGCoordinates(e.clientX, e.clientY);
|
|
16018
|
+
longPressStartPosRef.current = clickCoords;
|
|
16019
|
+
longPressEdgeIndexRef.current = edgeStartIndex;
|
|
16020
|
+
// 开始长按计时器(500ms)
|
|
16021
|
+
longPressTimerRef.current = window.setTimeout(() => {
|
|
16022
|
+
isLongPressedRef.current = true;
|
|
16023
|
+
// 长按触发,创建新顶点
|
|
16024
|
+
if (longPressEdgeIndexRef.current !== -1 && longPressStartPosRef.current) {
|
|
16025
|
+
handleEdgeClick(e, longPressEdgeIndexRef.current);
|
|
16026
|
+
}
|
|
16027
|
+
}, 500);
|
|
16028
|
+
}, [editMode, createMode, completed, dragState.isDragging, getSVGCoordinates, handleEdgeClick]);
|
|
16029
|
+
// 长按结束或取消
|
|
16030
|
+
const handleEdgeLongPressEnd = useCallback(() => {
|
|
16031
|
+
if (longPressTimerRef.current !== null) {
|
|
16032
|
+
window.clearTimeout(longPressTimerRef.current);
|
|
16033
|
+
longPressTimerRef.current = null;
|
|
16034
|
+
}
|
|
16035
|
+
isLongPressedRef.current = false;
|
|
16036
|
+
longPressStartPosRef.current = null;
|
|
16037
|
+
longPressEdgeIndexRef.current = -1;
|
|
16038
|
+
}, []);
|
|
16039
|
+
// H5平台长按顶点选中
|
|
16040
|
+
const vertexLongPressTimerRef = useRef(null);
|
|
16041
|
+
const isVertexLongPressedRef = useRef(false);
|
|
16042
|
+
const longPressVertexIndexRef = useRef(-1);
|
|
16043
|
+
// 长按拖拽判定相关
|
|
16044
|
+
const touchStartPosRef = useRef(null);
|
|
16045
|
+
const hasStartedDragViaLongPressRef = useRef(false);
|
|
16046
|
+
const DRAG_START_THRESHOLD = 8; // 像素阈值,超过则认为进入拖拽
|
|
16047
|
+
// H5平台双击检测
|
|
16048
|
+
const lastTapRef = useRef(0);
|
|
16049
|
+
const lastTapIndexRef = useRef(-1);
|
|
16050
|
+
const DOUBLE_TAP_DELAY = 300; // 双击检测间隔时间(ms)
|
|
16051
|
+
const handleVertexLongPressStart = useCallback((e, index) => {
|
|
16052
|
+
if ((!editMode && !(createMode && completed)) || dragState.isDragging)
|
|
16053
|
+
return;
|
|
16054
|
+
e.preventDefault();
|
|
16055
|
+
e.stopPropagation();
|
|
16056
|
+
longPressVertexIndexRef.current = index;
|
|
16057
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16058
|
+
touchStartPosRef.current = { x: e.clientX, y: e.clientY };
|
|
16059
|
+
// 开始长按计时器(1000ms)
|
|
16060
|
+
vertexLongPressTimerRef.current = window.setTimeout(() => {
|
|
16061
|
+
isVertexLongPressedRef.current = true;
|
|
16062
|
+
setSelectedVertexIndex(index);
|
|
16063
|
+
}, 1000);
|
|
16064
|
+
}, [editMode, createMode, completed, dragState.isDragging]);
|
|
16065
|
+
const handleVertexLongPressEnd = useCallback(() => {
|
|
16066
|
+
if (vertexLongPressTimerRef.current !== null) {
|
|
16067
|
+
window.clearTimeout(vertexLongPressTimerRef.current);
|
|
16068
|
+
vertexLongPressTimerRef.current = null;
|
|
16069
|
+
}
|
|
16070
|
+
isVertexLongPressedRef.current = false;
|
|
16071
|
+
longPressVertexIndexRef.current = -1;
|
|
16072
|
+
touchStartPosRef.current = null;
|
|
16073
|
+
}, []);
|
|
15956
16074
|
const showNotCreateCursor = useMemo(() => {
|
|
15957
16075
|
if (!dragState?.isDragging || !dragState?.currentPosition)
|
|
15958
16076
|
return false;
|
|
@@ -15982,6 +16100,11 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15982
16100
|
const clickTimerRef = useRef(null);
|
|
15983
16101
|
const mouseDownTimerRef = useRef(null);
|
|
15984
16102
|
const isDoubleClickingRef = useRef(false);
|
|
16103
|
+
// 长按事件相关
|
|
16104
|
+
const longPressTimerRef = useRef(null);
|
|
16105
|
+
const isLongPressedRef = useRef(false);
|
|
16106
|
+
const longPressStartPosRef = useRef(null);
|
|
16107
|
+
const longPressEdgeIndexRef = useRef(-1);
|
|
15985
16108
|
// 清理 requestAnimationFrame 和事件定时器
|
|
15986
16109
|
useEffect(() => {
|
|
15987
16110
|
return () => {
|
|
@@ -15997,6 +16120,14 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15997
16120
|
window.clearTimeout(mouseDownTimerRef.current);
|
|
15998
16121
|
mouseDownTimerRef.current = null;
|
|
15999
16122
|
}
|
|
16123
|
+
if (longPressTimerRef.current !== null) {
|
|
16124
|
+
window.clearTimeout(longPressTimerRef.current);
|
|
16125
|
+
longPressTimerRef.current = null;
|
|
16126
|
+
}
|
|
16127
|
+
if (vertexLongPressTimerRef.current !== null) {
|
|
16128
|
+
window.clearTimeout(vertexLongPressTimerRef.current);
|
|
16129
|
+
vertexLongPressTimerRef.current = null;
|
|
16130
|
+
}
|
|
16000
16131
|
};
|
|
16001
16132
|
}, []);
|
|
16002
16133
|
// 拖拽过程中更新坐标 - 使用节流优化性能
|
|
@@ -16024,6 +16155,40 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16024
16155
|
});
|
|
16025
16156
|
}
|
|
16026
16157
|
}, [dragState.isDragging, dragState.dragIndex, getSVGCoordinates]);
|
|
16158
|
+
// 处理 H5 顶点长按后的触摸移动以进入拖拽
|
|
16159
|
+
const handleVertexTouchMoveMaybeStartDrag = useCallback((e, idx) => {
|
|
16160
|
+
if (platform !== PlatformType.H5)
|
|
16161
|
+
return;
|
|
16162
|
+
if (dragState.isDragging)
|
|
16163
|
+
return; // 已在拖拽
|
|
16164
|
+
// 允许两种进入拖拽的途径:
|
|
16165
|
+
// 1) 长按该点
|
|
16166
|
+
// 2) 该点已处于选中态
|
|
16167
|
+
const canDragNow = isVertexLongPressedRef.current && longPressVertexIndexRef.current === idx;
|
|
16168
|
+
const canDragBecauseSelected = selectedVertexIndex === idx;
|
|
16169
|
+
if (!canDragNow && !canDragBecauseSelected)
|
|
16170
|
+
return;
|
|
16171
|
+
if (touchStartPosRef.current) {
|
|
16172
|
+
const dx = e.clientX - touchStartPosRef.current.x;
|
|
16173
|
+
const dy = e.clientY - touchStartPosRef.current.y;
|
|
16174
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
16175
|
+
if (dist >= DRAG_START_THRESHOLD) {
|
|
16176
|
+
// 进入拖拽状态
|
|
16177
|
+
const index = idx;
|
|
16178
|
+
hasStartedDragViaLongPressRef.current = true;
|
|
16179
|
+
// 启动与 mouseDown 相同的拖拽逻辑
|
|
16180
|
+
setDragState({
|
|
16181
|
+
isDragging: true,
|
|
16182
|
+
dragIndex: index,
|
|
16183
|
+
originalPosition: [...coordinates[index]],
|
|
16184
|
+
currentPosition: [...coordinates[index]],
|
|
16185
|
+
newVertexIndex: -1,
|
|
16186
|
+
edgeInfo: null,
|
|
16187
|
+
dragType: 'existing',
|
|
16188
|
+
});
|
|
16189
|
+
}
|
|
16190
|
+
}
|
|
16191
|
+
}, [platform, dragState.isDragging, coordinates, selectedVertexIndex]);
|
|
16027
16192
|
// 结束拖拽
|
|
16028
16193
|
const handleMouseUp = useCallback(() => {
|
|
16029
16194
|
console.log('handleMouseUp', JSON.stringify(dragState));
|
|
@@ -16079,9 +16244,12 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16079
16244
|
},
|
|
16080
16245
|
}, platform);
|
|
16081
16246
|
document.body.style.userSelect = 'none';
|
|
16247
|
+
// 禁止系统滚动和浏览器触摸手势,防止底层地图跟随移动
|
|
16248
|
+
document.body.style.touchAction = 'none';
|
|
16082
16249
|
return () => {
|
|
16083
16250
|
cleanup();
|
|
16084
16251
|
document.body.style.userSelect = '';
|
|
16252
|
+
document.body.style.touchAction = '';
|
|
16085
16253
|
};
|
|
16086
16254
|
}
|
|
16087
16255
|
else {
|
|
@@ -16146,6 +16314,45 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16146
16314
|
const ghostFirstMidpoint = createMode && mousePos && !completed && renderCoordinates.length >= 1
|
|
16147
16315
|
? calculateMidpoint(renderCoordinates[0], [mousePos.x, mousePos.y])
|
|
16148
16316
|
: null;
|
|
16317
|
+
// H5平台处理触摸双击
|
|
16318
|
+
const handleVertexDoubleTap = useCallback((index) => {
|
|
16319
|
+
const now = Date.now();
|
|
16320
|
+
const timeDelta = now - lastTapRef.current;
|
|
16321
|
+
// 检查是否为双击(300ms内,且是同一个点)
|
|
16322
|
+
if (timeDelta < DOUBLE_TAP_DELAY && lastTapIndexRef.current === index) {
|
|
16323
|
+
// 只有在选中点的情况下才允许删除
|
|
16324
|
+
if (selectedVertexIndex === index && onVertexDelete && coordinates.length > 3) {
|
|
16325
|
+
// 将渲染索引转换为原始points的索引
|
|
16326
|
+
onVertexDelete(renderCoordinates?.length - 1 - index);
|
|
16327
|
+
// 删除后立即取消拖拽状态,避免误触发拖动
|
|
16328
|
+
setDragState({
|
|
16329
|
+
isDragging: false,
|
|
16330
|
+
dragIndex: -1,
|
|
16331
|
+
originalPosition: null,
|
|
16332
|
+
currentPosition: null,
|
|
16333
|
+
newVertexIndex: -1,
|
|
16334
|
+
edgeInfo: null,
|
|
16335
|
+
dragType: null,
|
|
16336
|
+
});
|
|
16337
|
+
// 删除后取消选中状态
|
|
16338
|
+
setSelectedVertexIndex(-1);
|
|
16339
|
+
}
|
|
16340
|
+
// 重置点击时间
|
|
16341
|
+
lastTapRef.current = 0;
|
|
16342
|
+
lastTapIndexRef.current = -1;
|
|
16343
|
+
}
|
|
16344
|
+
else {
|
|
16345
|
+
// 记录本次点击
|
|
16346
|
+
lastTapRef.current = now;
|
|
16347
|
+
lastTapIndexRef.current = index;
|
|
16348
|
+
}
|
|
16349
|
+
}, [
|
|
16350
|
+
selectedVertexIndex,
|
|
16351
|
+
onVertexDelete,
|
|
16352
|
+
coordinates?.length,
|
|
16353
|
+
editMapInfo?.createMode,
|
|
16354
|
+
renderCoordinates?.length,
|
|
16355
|
+
]);
|
|
16149
16356
|
return (jsxs(Fragment, { children: [(editMode || (createMode && completed)) &&
|
|
16150
16357
|
dragState.isDragging &&
|
|
16151
16358
|
dragState.dragType !== 'new' &&
|
|
@@ -16154,7 +16361,7 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16154
16361
|
const prevIndex = (dragState.dragIndex - 1 + coordinates.length) % coordinates.length;
|
|
16155
16362
|
const nextIndex = (dragState.dragIndex + 1) % coordinates.length;
|
|
16156
16363
|
return (jsxs(Fragment, { children: [jsx("line", { x1: coordinates[prevIndex][0], y1: coordinates[prevIndex][1], x2: dragState.originalPosition[0], y2: dragState.originalPosition[1], stroke: strokeColor, strokeWidth: strokeWidth, strokeOpacity: 0.5, strokeDasharray: "5,5", pointerEvents: "none" }), jsx("line", { x1: dragState.originalPosition[0], y1: dragState.originalPosition[1], x2: coordinates[nextIndex][0], y2: coordinates[nextIndex][1], stroke: strokeColor, strokeWidth: strokeWidth, strokeOpacity: 0.5, strokeDasharray: "5,5", pointerEvents: "none" })] }));
|
|
16157
|
-
})()] })), renderCoordinates.length >= 3 && (jsx("polygon", { className:
|
|
16364
|
+
})()] })), renderCoordinates.length >= 3 && (jsx("polygon", { className: styles$2.polygonPathG, points: polygonPoints, fill: fillColor, fillOpacity: fillOpacity, stroke: "none" // 边框透明
|
|
16158
16365
|
, onClick: onPolygonClick })), jsxs("g", { className: styles$2.polygonPathG, children: [renderCoordinates.length >= 2 &&
|
|
16159
16366
|
pathSegments.map((segment, index) => {
|
|
16160
16367
|
if (segment.points.length < 2)
|
|
@@ -16172,9 +16379,16 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16172
16379
|
renderCoordinates.map((coord, index) => {
|
|
16173
16380
|
const nextCoord = renderCoordinates[(index + 1) % renderCoordinates.length];
|
|
16174
16381
|
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,
|
|
16382
|
+
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: {
|
|
16383
|
+
userSelect: 'none',
|
|
16384
|
+
WebkitUserSelect: 'none',
|
|
16385
|
+
WebkitTouchCallout: 'none',
|
|
16386
|
+
touchAction: 'none',
|
|
16387
|
+
}, vectorEffect: "non-scaling-stroke", ...(platform === PlatformType.H5
|
|
16176
16388
|
? {
|
|
16177
|
-
onTouchStart: createReactEventHandler((e) =>
|
|
16389
|
+
onTouchStart: createReactEventHandler((e) => handleEdgeLongPressStart(e, index)),
|
|
16390
|
+
onTouchEnd: createReactEventHandler(() => handleEdgeLongPressEnd()),
|
|
16391
|
+
onTouchCancel: createReactEventHandler(() => handleEdgeLongPressEnd()),
|
|
16178
16392
|
}
|
|
16179
16393
|
: {
|
|
16180
16394
|
onMouseDown: (e) => handleEdgeClick(e, index),
|
|
@@ -16197,14 +16411,27 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16197
16411
|
setHoverVertex(null);
|
|
16198
16412
|
},
|
|
16199
16413
|
}) }, `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)) &&
|
|
16414
|
+
}), 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, showFirstDistance: platform !== PlatformType.H5 }), 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
16415
|
renderCoordinates.map((coord, idx) => {
|
|
16202
16416
|
// 判断当前顶点的状态
|
|
16203
16417
|
const isLastPoint = idx === renderCoordinates.length - 1;
|
|
16204
16418
|
const canComplete = createMode && !completed && renderCoordinates.length >= 3 && isLastPoint;
|
|
16205
16419
|
const isCreatedAndCanDrag = createMode && completed; // 创建完成后可拖拽
|
|
16206
16420
|
const isInEditMode = editMode;
|
|
16207
|
-
|
|
16421
|
+
// H5模式下选中的顶点显示蓝色,并且放大1.5倍
|
|
16422
|
+
const isSelected = platform === PlatformType.H5 && selectedVertexIndex === idx;
|
|
16423
|
+
const vertexRadius = isSelected ? (canComplete ? 16 : 12) * 1.2 : canComplete ? 16 : 12;
|
|
16424
|
+
const vertexFill = isSelected ? '#FFAB7E' : 'white';
|
|
16425
|
+
return (jsxs("g", { children: [jsx(VertexElement, { className: generateVertexClassName, style: {
|
|
16426
|
+
userSelect: 'none',
|
|
16427
|
+
WebkitUserSelect: 'none',
|
|
16428
|
+
WebkitTouchCallout: 'none',
|
|
16429
|
+
touchAction: 'none',
|
|
16430
|
+
}, stroke: strokeColor, fill: vertexFill, cx: coord[0], cy: coord[1], r: vertexRadius, onClick: (e) => handleVertexClick(e, idx), onDoubleClick: (e) => {
|
|
16431
|
+
console.log('双击事件', selectedVertexIndex, idx);
|
|
16432
|
+
if (platform === PlatformType.H5) {
|
|
16433
|
+
return;
|
|
16434
|
+
}
|
|
16208
16435
|
// 阻止双击事件冒泡到Google Maps
|
|
16209
16436
|
e.preventDefault();
|
|
16210
16437
|
e.stopPropagation();
|
|
@@ -16222,12 +16449,6 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16222
16449
|
setTimeout(() => {
|
|
16223
16450
|
isDoubleClickingRef.current = false;
|
|
16224
16451
|
}, 300);
|
|
16225
|
-
if (platform === PlatformType.H5) {
|
|
16226
|
-
if (onVertexDelete && coordinates.length > 3) {
|
|
16227
|
-
onVertexDelete(idx);
|
|
16228
|
-
}
|
|
16229
|
-
return;
|
|
16230
|
-
}
|
|
16231
16452
|
// 打开删除确认 Tooltip(仅在可编辑时)
|
|
16232
16453
|
if (editMode || (createMode && completed)) {
|
|
16233
16454
|
setTooltipIndex(idx);
|
|
@@ -16235,12 +16456,51 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16235
16456
|
}, ...(platform === PlatformType.H5
|
|
16236
16457
|
? {
|
|
16237
16458
|
onTouchStart: createReactEventHandler((e) => {
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
|
|
16459
|
+
e.preventDefault();
|
|
16460
|
+
e.stopPropagation();
|
|
16461
|
+
// 如果不是支持拖拽的话,则不往下走
|
|
16462
|
+
if (!draggable) {
|
|
16463
|
+
return;
|
|
16464
|
+
}
|
|
16465
|
+
// 如果未选中,则走长按选中逻辑
|
|
16466
|
+
if (selectedVertexIndex !== idx) {
|
|
16467
|
+
handleVertexLongPressStart(e, idx);
|
|
16468
|
+
}
|
|
16469
|
+
else {
|
|
16470
|
+
// 已选中:准备可能的拖拽(记录起点),不阻塞双击
|
|
16471
|
+
touchStartPosRef.current = {
|
|
16472
|
+
x: e.clientX,
|
|
16473
|
+
y: e.clientY,
|
|
16474
|
+
};
|
|
16475
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16476
|
+
isVertexLongPressedRef.current = false;
|
|
16477
|
+
longPressVertexIndexRef.current = idx;
|
|
16478
|
+
}
|
|
16479
|
+
}),
|
|
16480
|
+
onTouchMove: createReactEventHandler((e) => {
|
|
16481
|
+
// 如果不是支持拖拽的话,则不往下走
|
|
16482
|
+
if (!draggable) {
|
|
16483
|
+
return;
|
|
16484
|
+
}
|
|
16485
|
+
// 长按后,超过阈值再进入拖拽
|
|
16486
|
+
handleVertexTouchMoveMaybeStartDrag(e, idx);
|
|
16487
|
+
}),
|
|
16488
|
+
onTouchEnd: createReactEventHandler(() => {
|
|
16489
|
+
// 如果不是支持拖拽的话,则不往下走
|
|
16490
|
+
if (!draggable) {
|
|
16491
|
+
return;
|
|
16243
16492
|
}
|
|
16493
|
+
// 如果已经通过长按进入拖拽,不触发双击检测
|
|
16494
|
+
const startedDrag = hasStartedDragViaLongPressRef.current;
|
|
16495
|
+
handleVertexLongPressEnd();
|
|
16496
|
+
if (!startedDrag && !isVertexLongPressedRef.current) {
|
|
16497
|
+
handleVertexDoubleTap(idx);
|
|
16498
|
+
}
|
|
16499
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16500
|
+
}),
|
|
16501
|
+
onTouchCancel: createReactEventHandler(() => {
|
|
16502
|
+
handleVertexLongPressEnd();
|
|
16503
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16244
16504
|
}),
|
|
16245
16505
|
}
|
|
16246
16506
|
: {
|
|
@@ -16313,19 +16573,26 @@ const BoundaryElement = ({ data }) => {
|
|
|
16313
16573
|
* 点击边界的回调
|
|
16314
16574
|
*/
|
|
16315
16575
|
const onPathClick = useCallback(() => {
|
|
16316
|
-
onSelectElement?.(DataType.BOUNDARY);
|
|
16576
|
+
onSelectElement?.(DataType.BOUNDARY, data);
|
|
16317
16577
|
if (platform === PlatformType.H5) {
|
|
16318
16578
|
// 对于地块来说,如果当前有元素是在编辑和创建模式下,则不进行选中
|
|
16319
16579
|
if (editMapInfo.mobileMode === MobileEditMode.EDIT ||
|
|
16320
16580
|
editMapInfo.mobileMode === MobileEditMode.CREATE) {
|
|
16321
16581
|
return;
|
|
16322
16582
|
}
|
|
16323
|
-
|
|
16324
|
-
|
|
16325
|
-
|
|
16326
|
-
|
|
16327
|
-
|
|
16328
|
-
|
|
16583
|
+
if (editMapInfo.selectElement?.id === data.id) {
|
|
16584
|
+
setEditMapInfo({
|
|
16585
|
+
...INIT_EDIT_MAP_INFO,
|
|
16586
|
+
});
|
|
16587
|
+
}
|
|
16588
|
+
else {
|
|
16589
|
+
setEditMapInfo((prev) => ({
|
|
16590
|
+
...prev,
|
|
16591
|
+
mobileMode: MobileEditMode.START,
|
|
16592
|
+
elementType: DataType.BOUNDARY,
|
|
16593
|
+
selectElement: data,
|
|
16594
|
+
}));
|
|
16595
|
+
}
|
|
16329
16596
|
}
|
|
16330
16597
|
else {
|
|
16331
16598
|
if (editMapInfo?.selectElement)
|
|
@@ -16338,7 +16605,9 @@ const BoundaryElement = ({ data }) => {
|
|
|
16338
16605
|
}));
|
|
16339
16606
|
}
|
|
16340
16607
|
}, [platform, data, editMapInfo]);
|
|
16341
|
-
return (jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: onPathClick,
|
|
16608
|
+
return (jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: onPathClick, onPolygonClick: () => {
|
|
16609
|
+
onPathClick();
|
|
16610
|
+
}, onCoordinatesChange: (coordinates) => {
|
|
16342
16611
|
console.log('onCoordinatesChange', coordinates);
|
|
16343
16612
|
setEditMapInfo((prev) => ({
|
|
16344
16613
|
...prev,
|
|
@@ -16454,31 +16723,32 @@ const useHistoryHandle = (props) => {
|
|
|
16454
16723
|
|
|
16455
16724
|
const ObstacleElement = ({ data }) => {
|
|
16456
16725
|
const style = data.style || {};
|
|
16457
|
-
const { editMapInfo, setEditMapInfo, onHandleEnterRecord } = useMapEditContext();
|
|
16726
|
+
const { editMapInfo, setEditMapInfo, onHandleEnterRecord, onSelectElement } = useMapEditContext();
|
|
16458
16727
|
const { platform } = useCommonContext();
|
|
16459
16728
|
const { disabledObstacles } = useSvgEditContext();
|
|
16460
16729
|
const { addHistory } = useHistoryHandle();
|
|
16461
16730
|
// 处理删除顶点
|
|
16462
16731
|
const handleCreateVertexDelete = useCallback((vertexIndex) => {
|
|
16732
|
+
console.log('ObstacleElement删除顶点', vertexIndex);
|
|
16463
16733
|
if (editMapInfo?.selectElement?.points && editMapInfo?.selectElement?.points?.length > 0) {
|
|
16464
16734
|
const newPoints = editMapInfo?.selectElement?.points?.filter((_, index) => index !== vertexIndex);
|
|
16735
|
+
console.log('newPoints', newPoints);
|
|
16465
16736
|
setEditMapInfo((prev) => ({
|
|
16466
16737
|
...prev,
|
|
16467
16738
|
selectElement: {
|
|
16468
16739
|
...prev.selectElement,
|
|
16469
|
-
points: newPoints,
|
|
16740
|
+
points: [...newPoints],
|
|
16470
16741
|
},
|
|
16471
16742
|
}));
|
|
16472
16743
|
addHistory({
|
|
16473
16744
|
selectElement: {
|
|
16474
16745
|
...editMapInfo.selectElement,
|
|
16475
|
-
points: newPoints,
|
|
16746
|
+
points: [...newPoints],
|
|
16476
16747
|
},
|
|
16477
16748
|
});
|
|
16478
16749
|
}
|
|
16479
16750
|
}, [editMapInfo]);
|
|
16480
16751
|
const currentPoints = useMemo(() => {
|
|
16481
|
-
// 为了方便解决删除顶点的时候,delete icon被遮挡的问题,所以逆序一下
|
|
16482
16752
|
if (editMapInfo?.selectElement?.id === data.id) {
|
|
16483
16753
|
return editMapInfo.selectElement.points;
|
|
16484
16754
|
}
|
|
@@ -16498,41 +16768,28 @@ const ObstacleElement = ({ data }) => {
|
|
|
16498
16768
|
return dp2px(style.lineWidth || 3);
|
|
16499
16769
|
}, [platform, style, editMapInfo]);
|
|
16500
16770
|
const onPathClick = useCallback(() => {
|
|
16771
|
+
onSelectElement?.(DataType.OBSTACLE, data);
|
|
16501
16772
|
if (platform === PlatformType.H5) {
|
|
16502
16773
|
// h5编辑模式下,禁区只有在start模式下才需要选中
|
|
16503
16774
|
if (editMapInfo.mobileMode === MobileEditMode.EDIT ||
|
|
16504
16775
|
editMapInfo.mobileMode === MobileEditMode.CREATE) {
|
|
16505
16776
|
return;
|
|
16506
16777
|
}
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16778
|
+
if (editMapInfo.selectElement?.id === data.id) {
|
|
16779
|
+
setEditMapInfo({
|
|
16780
|
+
...INIT_EDIT_MAP_INFO,
|
|
16781
|
+
});
|
|
16782
|
+
}
|
|
16783
|
+
else {
|
|
16784
|
+
setEditMapInfo((prev) => ({
|
|
16785
|
+
...prev,
|
|
16786
|
+
mobileMode: MobileEditMode.START,
|
|
16787
|
+
elementType: DataType.OBSTACLE,
|
|
16788
|
+
selectElement: data,
|
|
16789
|
+
}));
|
|
16790
|
+
}
|
|
16514
16791
|
}
|
|
16515
|
-
|
|
16516
|
-
return;
|
|
16517
|
-
onHandleEnterRecord?.({
|
|
16518
|
-
type: 3,
|
|
16519
|
-
function: 1,
|
|
16520
|
-
zoneId: data.id,
|
|
16521
|
-
})?.then(() => {
|
|
16522
|
-
setEditMapInfo((prev) => ({
|
|
16523
|
-
...prev,
|
|
16524
|
-
selectElement: data,
|
|
16525
|
-
historyList: [
|
|
16526
|
-
{
|
|
16527
|
-
selectElement: data,
|
|
16528
|
-
},
|
|
16529
|
-
],
|
|
16530
|
-
currentHistoryIndex: 0,
|
|
16531
|
-
elementType: DataType.OBSTACLE,
|
|
16532
|
-
editMap: true,
|
|
16533
|
-
}));
|
|
16534
|
-
});
|
|
16535
|
-
}, [disabledObstacles, data, onHandleEnterRecord, editMapInfo]);
|
|
16792
|
+
}, [data, editMapInfo, onSelectElement]);
|
|
16536
16793
|
const editMode = useMemo(() => {
|
|
16537
16794
|
if (platform === PlatformType.H5) {
|
|
16538
16795
|
return (editMapInfo?.mobileMode === MobileEditMode.EDIT &&
|
|
@@ -16541,10 +16798,9 @@ const ObstacleElement = ({ data }) => {
|
|
|
16541
16798
|
return editMapInfo?.selectElement?.id === data.id;
|
|
16542
16799
|
}, [editMapInfo, data, platform]);
|
|
16543
16800
|
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: () => {
|
|
16544
|
-
|
|
16545
|
-
onPathClick();
|
|
16546
|
-
}
|
|
16801
|
+
onPathClick();
|
|
16547
16802
|
}, onVertexDelete: (vertexIndex) => handleCreateVertexDelete(vertexIndex), onCoordinatesChange: (coordinates) => {
|
|
16803
|
+
console.log('onCoordinatesChange', coordinates);
|
|
16548
16804
|
if (platform === PlatformType.H5 && editMapInfo.mobileMode === MobileEditMode.CREATE) {
|
|
16549
16805
|
return;
|
|
16550
16806
|
}
|
|
@@ -17248,9 +17504,7 @@ const VisionOffTransformWrapper = ({ data, isSelected = false, onSelect, onCance
|
|
|
17248
17504
|
return (jsxs("g", { ref: containerRef, className: `vision-off-transform-wrapper ${className} ${isSelected ? 'selected' : ''}`, "data-transform-wrapper": "true", children: [jsx(PolygonElement, { points: visionOffData?.points, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: () => {
|
|
17249
17505
|
onSelect?.();
|
|
17250
17506
|
}, onPolygonClick: () => {
|
|
17251
|
-
|
|
17252
|
-
onSelect?.();
|
|
17253
|
-
}
|
|
17507
|
+
onSelect?.();
|
|
17254
17508
|
} }), isSelected && currentPoints.length === 4 && (jsx("polygon", { points: currentPoints.map((point) => `${point.x},${point.y}`).join(' '), fill: "transparent", stroke: "none", style: { cursor: 'move' }, ...(platform === PlatformType.H5
|
|
17255
17509
|
? {
|
|
17256
17510
|
onTouchStart: createReactEventHandler((e) => {
|
|
@@ -17332,7 +17586,7 @@ const VisionOffTransformWrapper = ({ data, isSelected = false, onSelect, onCance
|
|
|
17332
17586
|
};
|
|
17333
17587
|
|
|
17334
17588
|
const VisionOffElement = ({ data, onSelect }) => {
|
|
17335
|
-
const { setEditMapInfo, onHandleEnterRecord, editMapInfo } = useMapEditContext();
|
|
17589
|
+
const { setEditMapInfo, onHandleEnterRecord, editMapInfo, onSelectElement } = useMapEditContext();
|
|
17336
17590
|
const { addHistory } = useHistoryHandle();
|
|
17337
17591
|
const { platform } = useCommonContext();
|
|
17338
17592
|
const isSelected = useMemo(() => {
|
|
@@ -17345,18 +17599,16 @@ const VisionOffElement = ({ data, onSelect }) => {
|
|
|
17345
17599
|
return editMapInfo?.selectElement?.id === data.id;
|
|
17346
17600
|
}, [editMapInfo, data, platform]);
|
|
17347
17601
|
const handleSelect = useCallback(() => {
|
|
17602
|
+
onSelectElement?.(DataType.VISION_OFF, data);
|
|
17348
17603
|
if (platform === PlatformType.H5) {
|
|
17349
17604
|
// h5编辑模式下,
|
|
17350
17605
|
// start模式可以任意选
|
|
17351
|
-
// create或者是edit模式的话,只有选中的是visionOff
|
|
17352
|
-
if (
|
|
17353
|
-
editMapInfo.mobileMode === MobileEditMode.EDIT)
|
|
17354
|
-
editMapInfo.elementType !== DataType.VISION_OFF) {
|
|
17355
|
-
|
|
17356
|
-
|
|
17357
|
-
if ((editMapInfo.mobileMode === MobileEditMode.CREATE ||
|
|
17358
|
-
editMapInfo.mobileMode === MobileEditMode.EDIT) &&
|
|
17359
|
-
editMapInfo.elementType === DataType.VISION_OFF) {
|
|
17606
|
+
// create或者是edit模式的话,只有选中的是visionOff的时候才能操作
|
|
17607
|
+
if (editMapInfo.mobileMode === MobileEditMode.CREATE ||
|
|
17608
|
+
editMapInfo.mobileMode === MobileEditMode.EDIT) {
|
|
17609
|
+
if (editMapInfo.elementType !== DataType.VISION_OFF) {
|
|
17610
|
+
return;
|
|
17611
|
+
}
|
|
17360
17612
|
setEditMapInfo((prev) => ({
|
|
17361
17613
|
...prev,
|
|
17362
17614
|
selectElement: data,
|
|
@@ -17365,36 +17617,43 @@ const VisionOffElement = ({ data, onSelect }) => {
|
|
|
17365
17617
|
}));
|
|
17366
17618
|
return;
|
|
17367
17619
|
}
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17620
|
+
if (editMapInfo.selectElement?.id === data.id) {
|
|
17621
|
+
setEditMapInfo({
|
|
17622
|
+
...INIT_EDIT_MAP_INFO,
|
|
17623
|
+
});
|
|
17624
|
+
}
|
|
17625
|
+
else {
|
|
17626
|
+
setEditMapInfo((prev) => ({
|
|
17627
|
+
...prev,
|
|
17628
|
+
selectElement: data,
|
|
17629
|
+
elementType: DataType.VISION_OFF,
|
|
17630
|
+
mobileMode: MobileEditMode.START,
|
|
17631
|
+
}));
|
|
17632
|
+
}
|
|
17374
17633
|
return;
|
|
17375
17634
|
}
|
|
17376
17635
|
if (editMapInfo?.selectElement)
|
|
17377
17636
|
return;
|
|
17378
|
-
return onHandleEnterRecord?.({
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
})?.then(() => {
|
|
17382
|
-
|
|
17383
|
-
|
|
17384
|
-
|
|
17385
|
-
|
|
17386
|
-
|
|
17387
|
-
|
|
17388
|
-
|
|
17389
|
-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
});
|
|
17397
|
-
}, [data, onHandleEnterRecord, platform, editMapInfo]);
|
|
17637
|
+
// return onHandleEnterRecord?.({
|
|
17638
|
+
// type: 2,
|
|
17639
|
+
// function: 1,
|
|
17640
|
+
// })?.then(() => {
|
|
17641
|
+
// onSelect?.();
|
|
17642
|
+
// setEditMapInfo((prev: EditMapInfo) => ({
|
|
17643
|
+
// ...prev,
|
|
17644
|
+
// selectElement: data,
|
|
17645
|
+
// elementType: DataType.VISION_OFF,
|
|
17646
|
+
// historyList: [
|
|
17647
|
+
// {
|
|
17648
|
+
// selectElement: data,
|
|
17649
|
+
// },
|
|
17650
|
+
// ],
|
|
17651
|
+
// currentHistoryIndex: 0,
|
|
17652
|
+
// editMap: true,
|
|
17653
|
+
// isShowDrag: true,
|
|
17654
|
+
// }));
|
|
17655
|
+
// });
|
|
17656
|
+
}, [data, onHandleEnterRecord, platform, editMapInfo, onSelectElement]);
|
|
17398
17657
|
const onCancel = useCallback(() => {
|
|
17399
17658
|
if (platform === PlatformType.H5) {
|
|
17400
17659
|
// 在h5中,这里的取消其实对应的是删除元素
|
|
@@ -17882,7 +18141,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
|
|
|
17882
18141
|
}, [data]);
|
|
17883
18142
|
const remainingTime = useMemo(() => {
|
|
17884
18143
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
17885
|
-
console.log('data.expiration_ts--', data.expiration_ts);
|
|
18144
|
+
// console.log('data.expiration_ts--', data.expiration_ts);
|
|
17886
18145
|
if (data.expiration_ts <= currentTime) {
|
|
17887
18146
|
return 0;
|
|
17888
18147
|
}
|
|
@@ -18127,7 +18386,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
|
|
|
18127
18386
|
};
|
|
18128
18387
|
|
|
18129
18388
|
const DoodleElement = ({ data }) => {
|
|
18130
|
-
const { editMapInfo, setEditMapInfo,
|
|
18389
|
+
const { editMapInfo, setEditMapInfo, onHandleEvent, onSelectElement } = useMapEditContext();
|
|
18131
18390
|
const { addHistory } = useHistoryHandle();
|
|
18132
18391
|
const { platform, doodleList } = useCommonContext();
|
|
18133
18392
|
const isSelected = useMemo(() => {
|
|
@@ -18176,6 +18435,7 @@ const DoodleElement = ({ data }) => {
|
|
|
18176
18435
|
}, [data]);
|
|
18177
18436
|
const handleTransformChange = (transform) => { };
|
|
18178
18437
|
const handleSelect = useCallback(() => {
|
|
18438
|
+
onSelectElement?.(DataType.DOODLE, data);
|
|
18179
18439
|
if (platform === PlatformType.H5) {
|
|
18180
18440
|
// h5编辑模式下,
|
|
18181
18441
|
// 如果是创建,只能选择新建的doodle
|
|
@@ -18183,7 +18443,7 @@ const DoodleElement = ({ data }) => {
|
|
|
18183
18443
|
editMapInfo.mobileMode === MobileEditMode.EDIT) {
|
|
18184
18444
|
return;
|
|
18185
18445
|
}
|
|
18186
|
-
//
|
|
18446
|
+
// 如果start模式下
|
|
18187
18447
|
setEditMapInfo((prev) => ({
|
|
18188
18448
|
...prev,
|
|
18189
18449
|
selectElement: data,
|
|
@@ -18192,34 +18452,29 @@ const DoodleElement = ({ data }) => {
|
|
|
18192
18452
|
}));
|
|
18193
18453
|
return;
|
|
18194
18454
|
}
|
|
18195
|
-
if (editMapInfo?.selectElement) {
|
|
18196
|
-
|
|
18197
|
-
}
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
editMap: true,
|
|
18219
|
-
isShowDrag: true,
|
|
18220
|
-
}));
|
|
18221
|
-
});
|
|
18222
|
-
}, [data, onHandleEnterRecord, platform, editMapInfo]);
|
|
18455
|
+
// if (editMapInfo?.selectElement) {
|
|
18456
|
+
// return;
|
|
18457
|
+
// }
|
|
18458
|
+
// setEditMapInfo((prev: EditMapInfo) => ({
|
|
18459
|
+
// ...prev,
|
|
18460
|
+
// historyList: [
|
|
18461
|
+
// {
|
|
18462
|
+
// selectElement: {
|
|
18463
|
+
// ...data,
|
|
18464
|
+
// transformedPoints: transformedElements,
|
|
18465
|
+
// },
|
|
18466
|
+
// },
|
|
18467
|
+
// ],
|
|
18468
|
+
// currentHistoryIndex: 0,
|
|
18469
|
+
// selectElement: {
|
|
18470
|
+
// ...data,
|
|
18471
|
+
// transformedPoints: transformedElements,
|
|
18472
|
+
// },
|
|
18473
|
+
// elementType: DataType.DOODLE,
|
|
18474
|
+
// editMap: true,
|
|
18475
|
+
// isShowDrag: true,
|
|
18476
|
+
// }));
|
|
18477
|
+
}, [data, platform, editMapInfo, onSelectElement]);
|
|
18223
18478
|
const handleCancel = useCallback(() => {
|
|
18224
18479
|
if (platform === PlatformType.H5) {
|
|
18225
18480
|
setEditMapInfo((prev) => ({
|
|
@@ -18269,7 +18524,6 @@ const DoodleElement = ({ data }) => {
|
|
|
18269
18524
|
},
|
|
18270
18525
|
});
|
|
18271
18526
|
}, [transformedElements]);
|
|
18272
|
-
console.log('isSelectedWithoutOperation--->', editMapInfo, isSelectedWithoutOperation, isSelected);
|
|
18273
18527
|
return (jsx(DoodleTransformWrapper, { data: originData, onTransformChange: handleTransformChange, isSelected: isSelected, isSelectedWithoutOperation: isSelectedWithoutOperation, onSelect: handleSelect, onCancel: handleCancel, onDragEnd: handleDragEnd, showInfo: platform === PlatformType.H5, onClickInfo: handleClickInfo, minScale: minScale }));
|
|
18274
18528
|
};
|
|
18275
18529
|
|
|
@@ -19313,7 +19567,7 @@ function usePolygonDrawing(options = {}) {
|
|
|
19313
19567
|
const { checkCanNotCreateAtPosition } = useCheckElement();
|
|
19314
19568
|
const { addHistory } = useHistoryHandle();
|
|
19315
19569
|
const points = useMemo(() => {
|
|
19316
|
-
console.log('points->', editMapInfo?.selectElement?.points);
|
|
19570
|
+
// console.log('points->', editMapInfo?.selectElement?.points);
|
|
19317
19571
|
return editMapInfo?.selectElement?.points?.map((item) => ({ x: item[0], y: item[1] })) || [];
|
|
19318
19572
|
}, [editMapInfo?.selectElement?.points]);
|
|
19319
19573
|
const completed = useMemo(() => {
|
|
@@ -20457,13 +20711,6 @@ modelType, mapRef, mapJson, pathJson, realTimeData, antennaConfig, onMapLoad, on
|
|
|
20457
20711
|
const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
|
|
20458
20712
|
console.log('scale', scale, currentZoom, zoomDiff);
|
|
20459
20713
|
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
20714
|
};
|
|
20468
20715
|
// 使用lodash throttle进行节流处理: 100ms内只执行一次
|
|
20469
20716
|
const handleZoomChanged = throttle$2(updateScale, 50);
|