@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.js
CHANGED
|
@@ -313,7 +313,7 @@ function initObstacle() {
|
|
|
313
313
|
const obstacle = {
|
|
314
314
|
id: null,
|
|
315
315
|
area: 0,
|
|
316
|
-
name: '
|
|
316
|
+
name: 'Noname',
|
|
317
317
|
status: 1,
|
|
318
318
|
end_timestamp: 0,
|
|
319
319
|
start_timestamp: 0,
|
|
@@ -15092,10 +15092,10 @@ const DashPath = ({ points, stroke, strokeWidth, strokeOpacity, className, }) =>
|
|
|
15092
15092
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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' } }), jsxRuntime.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' } })] }));
|
|
15093
15093
|
};
|
|
15094
15094
|
|
|
15095
|
-
const VertexElement = React.memo(({ r, stroke, ...props }) => {
|
|
15096
|
-
const { overlayScale } = useCommonContext();
|
|
15095
|
+
const VertexElement = React.memo(({ r, stroke, fill, ...props }) => {
|
|
15096
|
+
const { overlayScale, platform } = useCommonContext();
|
|
15097
15097
|
const radius = typeof r === 'number' ? r : 12;
|
|
15098
|
-
return (jsxRuntime.jsx("circle", { r: radius * overlayScale, stroke: stroke || '#fff', fill: '#fff', strokeWidth: 2 * overlayScale, ...props }));
|
|
15098
|
+
return (jsxRuntime.jsx("circle", { r: platform === exports.PlatformType.H5 ? (radius * overlayScale) / 2 : radius * overlayScale, stroke: stroke || '#fff', fill: fill || '#fff', strokeWidth: 2 * overlayScale, ...props }));
|
|
15099
15099
|
});
|
|
15100
15100
|
|
|
15101
15101
|
var _path$2;
|
|
@@ -15179,6 +15179,7 @@ const normalizePadding = (padding) => {
|
|
|
15179
15179
|
return { x: padding?.x ?? 4, y: padding?.y ?? 2 };
|
|
15180
15180
|
};
|
|
15181
15181
|
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, }) => {
|
|
15182
|
+
const { platform } = useCommonContext();
|
|
15182
15183
|
const textRef = React.useRef(null);
|
|
15183
15184
|
const [bbox, setBbox] = React.useState(null);
|
|
15184
15185
|
const pad = React.useMemo(() => normalizePadding(padding), [padding]);
|
|
@@ -15205,7 +15206,7 @@ const TextElement = ({ x, y, fontSize = 30, fill = '#fff', text, background = 'r
|
|
|
15205
15206
|
height: bbox.height + pad.y * 2,
|
|
15206
15207
|
};
|
|
15207
15208
|
}, [bbox, pad.x, pad.y]);
|
|
15208
|
-
return (jsxRuntime.jsxs("g", { className: className, style: style, pointerEvents: pointerEvents, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, children: [background && rectProps && (jsxRuntime.jsx("rect", { x: rectProps.x, y: rectProps.y, width: rectProps.width, height: rectProps.height, rx: rx, ry: ry, fill: background, stroke: backgroundStroke, strokeWidth: backgroundStrokeWidth })), jsxRuntime.jsx("text", { ref: textRef, x: x, y: y, letterSpacing: -5, fontSize: fontSize, fill: fill, textAnchor: textAnchor, alignmentBaseline: alignmentBaseline,
|
|
15209
|
+
return (jsxRuntime.jsxs("g", { className: className, style: style, pointerEvents: pointerEvents, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, children: [background && rectProps && (jsxRuntime.jsx("rect", { x: rectProps.x, y: rectProps.y, width: rectProps.width, height: rectProps.height, rx: rx, ry: ry, fill: background, stroke: backgroundStroke, strokeWidth: backgroundStrokeWidth })), jsxRuntime.jsx("text", { ref: textRef, x: x, y: y, letterSpacing: platform === exports.PlatformType.H5 ? 1 : -5, fontSize: fontSize, fill: fill, textAnchor: textAnchor, alignmentBaseline: alignmentBaseline,
|
|
15209
15210
|
// keep text crisp at various zoom levels
|
|
15210
15211
|
vectorEffect: "non-scaling-stroke", style: { pointerEvents: 'none' }, children: children || text })] }));
|
|
15211
15212
|
};
|
|
@@ -15232,10 +15233,10 @@ const calculatePhysicalDistance$1 = (point1, point2) => {
|
|
|
15232
15233
|
const calculateMidpoint$1 = (point1, point2) => {
|
|
15233
15234
|
return [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2];
|
|
15234
15235
|
};
|
|
15235
|
-
const DistanceLabels = ({ coordinates, createMode = false, editMode = false, completed = false, showPoints = false, mousePos: _mousePos = null, ghostLastDistance = null, ghostLastMidpoint = null, ghostFirstDistance = null, ghostFirstMidpoint = null, fontSize = 30, }) => {
|
|
15236
|
+
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, }) => {
|
|
15236
15237
|
// 只在显示可操作顶点时显示距离
|
|
15237
15238
|
if (!((createMode && showPoints) || editMode || (createMode && completed)) ||
|
|
15238
|
-
coordinates.length < 1) {
|
|
15239
|
+
coordinates.length < (showFirstDistance ? 1 : 2)) {
|
|
15239
15240
|
return null;
|
|
15240
15241
|
}
|
|
15241
15242
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [coordinates.map((coord, idx) => {
|
|
@@ -15247,14 +15248,32 @@ const DistanceLabels = ({ coordinates, createMode = false, editMode = false, com
|
|
|
15247
15248
|
}
|
|
15248
15249
|
const midpoint = calculateMidpoint$1(coord, nextCoord);
|
|
15249
15250
|
const distance = calculatePhysicalDistance$1(coord, nextCoord);
|
|
15251
|
+
// 如果当前点和下一个点坐标一致则不现实,处理头尾点一样的问题
|
|
15252
|
+
if (coord[0] === nextCoord[0] && coord[1] === nextCoord[1]) {
|
|
15253
|
+
return null;
|
|
15254
|
+
}
|
|
15250
15255
|
return (jsxRuntime.jsx(TextElement, { x: midpoint[0], y: midpoint[1], textAnchor: "middle", alignmentBaseline: "middle", fontSize: fontSize, fill: "#fff", style: {
|
|
15251
15256
|
pointerEvents: 'none',
|
|
15252
15257
|
fontWeight: 'bold',
|
|
15258
|
+
userSelect: 'none',
|
|
15259
|
+
WebkitUserSelect: 'none',
|
|
15260
|
+
WebkitTouchCallout: 'none',
|
|
15261
|
+
touchAction: 'none',
|
|
15253
15262
|
}, text: distance }, `distance-${idx}`));
|
|
15254
|
-
}), ghostLastDistance && ghostLastMidpoint && (jsxRuntime.jsx(TextElement, { fontSize: fontSize, x: ghostLastMidpoint[0], y: ghostLastMidpoint[1], text: ghostLastDistance
|
|
15263
|
+
}), ghostLastDistance && ghostLastMidpoint && (jsxRuntime.jsx(TextElement, { fontSize: fontSize, x: ghostLastMidpoint[0], y: ghostLastMidpoint[1], text: ghostLastDistance, style: {
|
|
15264
|
+
userSelect: 'none',
|
|
15265
|
+
WebkitUserSelect: 'none',
|
|
15266
|
+
WebkitTouchCallout: 'none',
|
|
15267
|
+
touchAction: 'none',
|
|
15268
|
+
} })), ghostFirstDistance && ghostFirstMidpoint && (jsxRuntime.jsx(TextElement, { fontSize: fontSize, x: ghostFirstMidpoint[0], y: ghostFirstMidpoint[1], text: ghostFirstDistance, style: {
|
|
15269
|
+
userSelect: 'none',
|
|
15270
|
+
WebkitUserSelect: 'none',
|
|
15271
|
+
WebkitTouchCallout: 'none',
|
|
15272
|
+
touchAction: 'none',
|
|
15273
|
+
} }))] }));
|
|
15255
15274
|
};
|
|
15256
15275
|
|
|
15257
|
-
var css_248z$2 = ".index-module_polygonPathG__S-Bpl {\n
|
|
15276
|
+
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}";
|
|
15258
15277
|
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"};
|
|
15259
15278
|
styleInject(css_248z$2);
|
|
15260
15279
|
|
|
@@ -15547,6 +15566,7 @@ function coordinatesToPoints$1(coordinates) {
|
|
|
15547
15566
|
|
|
15548
15567
|
const useCheckElement = () => {
|
|
15549
15568
|
const { editMapInfo, minDistance } = useMapEditContext();
|
|
15569
|
+
const { platform } = useCommonContext();
|
|
15550
15570
|
const { svgElementDatas } = useSvgEditContext();
|
|
15551
15571
|
const checkDoodle = React.useCallback(() => {
|
|
15552
15572
|
console.log('checkdoodle', editMapInfo, svgElementDatas);
|
|
@@ -15647,7 +15667,7 @@ const useCheckElement = () => {
|
|
|
15647
15667
|
return { isValid: true };
|
|
15648
15668
|
}, [editMapInfo, svgElementDatas, minDistance]);
|
|
15649
15669
|
const checkCanNotCreateAtPosition = React.useCallback((checkPoint, checkPoints) => {
|
|
15650
|
-
console.log('editMapInfo.elementType--->', editMapInfo);
|
|
15670
|
+
// console.log('editMapInfo.elementType--->', editMapInfo);
|
|
15651
15671
|
if (!editMapInfo.elementType)
|
|
15652
15672
|
return false;
|
|
15653
15673
|
const currentPoints = editMapInfo?.selectElement?.points;
|
|
@@ -15674,8 +15694,10 @@ const useCheckElement = () => {
|
|
|
15674
15694
|
return false;
|
|
15675
15695
|
// 获取当前正在创建的 obstacle 的点
|
|
15676
15696
|
const currentObstaclePoints = coordinatesToPoints$1(points) || [];
|
|
15677
|
-
if (
|
|
15678
|
-
|
|
15697
|
+
if (platform !== exports.PlatformType.H5) {
|
|
15698
|
+
if (currentObstaclePoints.length === 0)
|
|
15699
|
+
return false; // 还没有开始绘制
|
|
15700
|
+
}
|
|
15679
15701
|
// 构建当前 obstacle 的多边形(包括检查点位置)
|
|
15680
15702
|
const currentObstaclePolygon = [...currentObstaclePoints, checkPoint];
|
|
15681
15703
|
// 获取当前边界内的所有元素
|
|
@@ -15831,12 +15853,21 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15831
15853
|
});
|
|
15832
15854
|
// 虚拟顶点hover状态
|
|
15833
15855
|
const [hoverVertex, setHoverVertex] = React.useState(null);
|
|
15856
|
+
// H5平台选中的顶点索引(长按后选中)
|
|
15857
|
+
const [selectedVertexIndex, setSelectedVertexIndex] = React.useState(-1);
|
|
15834
15858
|
const { checkCanNotCreateAtPosition } = useCheckElement();
|
|
15835
15859
|
const { editMapInfo } = useMapEditContext();
|
|
15836
15860
|
const { platform } = useCommonContext();
|
|
15837
15861
|
// delete icon可能被上一个点遮挡,因为delete在右上方,所以手动处理点让点按照顺时针渲染,这样delete icon层级就会高一些
|
|
15862
|
+
// 禁区的点最后一个和第一个相同,会导致一个位置渲染两个点,需要额外处理下
|
|
15838
15863
|
const coordinates = React.useMemo(() => {
|
|
15839
|
-
|
|
15864
|
+
const temp = editMapInfo?.createMode === exports.CreateStatus.CREATING ? points : [...points].reverse();
|
|
15865
|
+
const firstPoint = temp[0] || [];
|
|
15866
|
+
const lastPoint = temp[temp.length - 1] || [];
|
|
15867
|
+
if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
|
|
15868
|
+
return temp.slice(0, -1);
|
|
15869
|
+
}
|
|
15870
|
+
return temp;
|
|
15840
15871
|
}, [points, editMapInfo?.createMode]);
|
|
15841
15872
|
// 计算点到线段的垂足坐标(使用通用工具函数)
|
|
15842
15873
|
const calculatePerpendicularFoot$1 = React.useCallback((point, lineStart, lineEnd) => {
|
|
@@ -15898,11 +15929,33 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15898
15929
|
if (tooltipIndex !== null)
|
|
15899
15930
|
setTooltipIndex(null);
|
|
15900
15931
|
}, [editMode, createMode, completed]);
|
|
15932
|
+
// H5平台:点击空白处取消选中状态
|
|
15933
|
+
React.useEffect(() => {
|
|
15934
|
+
if (platform !== exports.PlatformType.H5 || selectedVertexIndex === -1)
|
|
15935
|
+
return;
|
|
15936
|
+
const handleDocumentClick = (e) => {
|
|
15937
|
+
// 检查点击的目标是否是顶点
|
|
15938
|
+
const target = e.target;
|
|
15939
|
+
const isClickingVertex = target.closest('circle') !== null;
|
|
15940
|
+
// 如果点击的不是顶点,则取消选中状态
|
|
15941
|
+
if (!isClickingVertex) {
|
|
15942
|
+
setSelectedVertexIndex(-1);
|
|
15943
|
+
}
|
|
15944
|
+
};
|
|
15945
|
+
document.addEventListener('click', handleDocumentClick);
|
|
15946
|
+
return () => {
|
|
15947
|
+
document.removeEventListener('click', handleDocumentClick);
|
|
15948
|
+
};
|
|
15949
|
+
}, [platform, selectedVertexIndex]);
|
|
15901
15950
|
// 处理顶点拖拽
|
|
15902
15951
|
const handleVertexMouseDown = React.useCallback((e, index) => {
|
|
15903
15952
|
// 只有在编辑模式或者创建模式已完成时才能拖拽
|
|
15904
15953
|
if (!editMode && !(createMode && completed))
|
|
15905
15954
|
return;
|
|
15955
|
+
// H5模式下,只有选中的顶点才能拖拽
|
|
15956
|
+
if (platform === exports.PlatformType.H5 && selectedVertexIndex !== index) {
|
|
15957
|
+
return;
|
|
15958
|
+
}
|
|
15906
15959
|
e.preventDefault();
|
|
15907
15960
|
e.stopPropagation();
|
|
15908
15961
|
// 如果正在双击,忽略mouseDown事件
|
|
@@ -15929,7 +15982,7 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15929
15982
|
});
|
|
15930
15983
|
mouseDownTimerRef.current = null;
|
|
15931
15984
|
}, 250);
|
|
15932
|
-
}, [editMode, createMode, completed, coordinates, tooltipIndex]);
|
|
15985
|
+
}, [editMode, createMode, completed, coordinates, tooltipIndex, platform, selectedVertexIndex]);
|
|
15933
15986
|
// 点击边线创建新顶点
|
|
15934
15987
|
const handleEdgeClick = React.useCallback((e, edgeStartIndex) => {
|
|
15935
15988
|
// 只有在编辑模式或者创建模式已完成时才能点击边线创建新顶点
|
|
@@ -15964,6 +16017,8 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15964
16017
|
edgeInfo: edgeInfo,
|
|
15965
16018
|
dragType: 'new',
|
|
15966
16019
|
});
|
|
16020
|
+
// 将新创建的点设为选中态,便于后续直接拖拽
|
|
16021
|
+
setSelectedVertexIndex(insertIndex);
|
|
15967
16022
|
}, [
|
|
15968
16023
|
editMode,
|
|
15969
16024
|
createMode,
|
|
@@ -15973,6 +16028,69 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
15973
16028
|
getSVGCoordinates,
|
|
15974
16029
|
calculatePerpendicularFoot$1,
|
|
15975
16030
|
]);
|
|
16031
|
+
// H5平台长按边线创建新顶点
|
|
16032
|
+
const handleEdgeLongPressStart = React.useCallback((e, edgeStartIndex) => {
|
|
16033
|
+
if ((!editMode && !(createMode && completed)) || dragState.isDragging)
|
|
16034
|
+
return;
|
|
16035
|
+
e.preventDefault();
|
|
16036
|
+
e.stopPropagation();
|
|
16037
|
+
const clickCoords = getSVGCoordinates(e.clientX, e.clientY);
|
|
16038
|
+
longPressStartPosRef.current = clickCoords;
|
|
16039
|
+
longPressEdgeIndexRef.current = edgeStartIndex;
|
|
16040
|
+
// 开始长按计时器(500ms)
|
|
16041
|
+
longPressTimerRef.current = window.setTimeout(() => {
|
|
16042
|
+
isLongPressedRef.current = true;
|
|
16043
|
+
// 长按触发,创建新顶点
|
|
16044
|
+
if (longPressEdgeIndexRef.current !== -1 && longPressStartPosRef.current) {
|
|
16045
|
+
handleEdgeClick(e, longPressEdgeIndexRef.current);
|
|
16046
|
+
}
|
|
16047
|
+
}, 500);
|
|
16048
|
+
}, [editMode, createMode, completed, dragState.isDragging, getSVGCoordinates, handleEdgeClick]);
|
|
16049
|
+
// 长按结束或取消
|
|
16050
|
+
const handleEdgeLongPressEnd = React.useCallback(() => {
|
|
16051
|
+
if (longPressTimerRef.current !== null) {
|
|
16052
|
+
window.clearTimeout(longPressTimerRef.current);
|
|
16053
|
+
longPressTimerRef.current = null;
|
|
16054
|
+
}
|
|
16055
|
+
isLongPressedRef.current = false;
|
|
16056
|
+
longPressStartPosRef.current = null;
|
|
16057
|
+
longPressEdgeIndexRef.current = -1;
|
|
16058
|
+
}, []);
|
|
16059
|
+
// H5平台长按顶点选中
|
|
16060
|
+
const vertexLongPressTimerRef = React.useRef(null);
|
|
16061
|
+
const isVertexLongPressedRef = React.useRef(false);
|
|
16062
|
+
const longPressVertexIndexRef = React.useRef(-1);
|
|
16063
|
+
// 长按拖拽判定相关
|
|
16064
|
+
const touchStartPosRef = React.useRef(null);
|
|
16065
|
+
const hasStartedDragViaLongPressRef = React.useRef(false);
|
|
16066
|
+
const DRAG_START_THRESHOLD = 8; // 像素阈值,超过则认为进入拖拽
|
|
16067
|
+
// H5平台双击检测
|
|
16068
|
+
const lastTapRef = React.useRef(0);
|
|
16069
|
+
const lastTapIndexRef = React.useRef(-1);
|
|
16070
|
+
const DOUBLE_TAP_DELAY = 300; // 双击检测间隔时间(ms)
|
|
16071
|
+
const handleVertexLongPressStart = React.useCallback((e, index) => {
|
|
16072
|
+
if ((!editMode && !(createMode && completed)) || dragState.isDragging)
|
|
16073
|
+
return;
|
|
16074
|
+
e.preventDefault();
|
|
16075
|
+
e.stopPropagation();
|
|
16076
|
+
longPressVertexIndexRef.current = index;
|
|
16077
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16078
|
+
touchStartPosRef.current = { x: e.clientX, y: e.clientY };
|
|
16079
|
+
// 开始长按计时器(1000ms)
|
|
16080
|
+
vertexLongPressTimerRef.current = window.setTimeout(() => {
|
|
16081
|
+
isVertexLongPressedRef.current = true;
|
|
16082
|
+
setSelectedVertexIndex(index);
|
|
16083
|
+
}, 1000);
|
|
16084
|
+
}, [editMode, createMode, completed, dragState.isDragging]);
|
|
16085
|
+
const handleVertexLongPressEnd = React.useCallback(() => {
|
|
16086
|
+
if (vertexLongPressTimerRef.current !== null) {
|
|
16087
|
+
window.clearTimeout(vertexLongPressTimerRef.current);
|
|
16088
|
+
vertexLongPressTimerRef.current = null;
|
|
16089
|
+
}
|
|
16090
|
+
isVertexLongPressedRef.current = false;
|
|
16091
|
+
longPressVertexIndexRef.current = -1;
|
|
16092
|
+
touchStartPosRef.current = null;
|
|
16093
|
+
}, []);
|
|
15976
16094
|
const showNotCreateCursor = React.useMemo(() => {
|
|
15977
16095
|
if (!dragState?.isDragging || !dragState?.currentPosition)
|
|
15978
16096
|
return false;
|
|
@@ -16002,6 +16120,11 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16002
16120
|
const clickTimerRef = React.useRef(null);
|
|
16003
16121
|
const mouseDownTimerRef = React.useRef(null);
|
|
16004
16122
|
const isDoubleClickingRef = React.useRef(false);
|
|
16123
|
+
// 长按事件相关
|
|
16124
|
+
const longPressTimerRef = React.useRef(null);
|
|
16125
|
+
const isLongPressedRef = React.useRef(false);
|
|
16126
|
+
const longPressStartPosRef = React.useRef(null);
|
|
16127
|
+
const longPressEdgeIndexRef = React.useRef(-1);
|
|
16005
16128
|
// 清理 requestAnimationFrame 和事件定时器
|
|
16006
16129
|
React.useEffect(() => {
|
|
16007
16130
|
return () => {
|
|
@@ -16017,6 +16140,14 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16017
16140
|
window.clearTimeout(mouseDownTimerRef.current);
|
|
16018
16141
|
mouseDownTimerRef.current = null;
|
|
16019
16142
|
}
|
|
16143
|
+
if (longPressTimerRef.current !== null) {
|
|
16144
|
+
window.clearTimeout(longPressTimerRef.current);
|
|
16145
|
+
longPressTimerRef.current = null;
|
|
16146
|
+
}
|
|
16147
|
+
if (vertexLongPressTimerRef.current !== null) {
|
|
16148
|
+
window.clearTimeout(vertexLongPressTimerRef.current);
|
|
16149
|
+
vertexLongPressTimerRef.current = null;
|
|
16150
|
+
}
|
|
16020
16151
|
};
|
|
16021
16152
|
}, []);
|
|
16022
16153
|
// 拖拽过程中更新坐标 - 使用节流优化性能
|
|
@@ -16044,6 +16175,40 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16044
16175
|
});
|
|
16045
16176
|
}
|
|
16046
16177
|
}, [dragState.isDragging, dragState.dragIndex, getSVGCoordinates]);
|
|
16178
|
+
// 处理 H5 顶点长按后的触摸移动以进入拖拽
|
|
16179
|
+
const handleVertexTouchMoveMaybeStartDrag = React.useCallback((e, idx) => {
|
|
16180
|
+
if (platform !== exports.PlatformType.H5)
|
|
16181
|
+
return;
|
|
16182
|
+
if (dragState.isDragging)
|
|
16183
|
+
return; // 已在拖拽
|
|
16184
|
+
// 允许两种进入拖拽的途径:
|
|
16185
|
+
// 1) 长按该点
|
|
16186
|
+
// 2) 该点已处于选中态
|
|
16187
|
+
const canDragNow = isVertexLongPressedRef.current && longPressVertexIndexRef.current === idx;
|
|
16188
|
+
const canDragBecauseSelected = selectedVertexIndex === idx;
|
|
16189
|
+
if (!canDragNow && !canDragBecauseSelected)
|
|
16190
|
+
return;
|
|
16191
|
+
if (touchStartPosRef.current) {
|
|
16192
|
+
const dx = e.clientX - touchStartPosRef.current.x;
|
|
16193
|
+
const dy = e.clientY - touchStartPosRef.current.y;
|
|
16194
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
16195
|
+
if (dist >= DRAG_START_THRESHOLD) {
|
|
16196
|
+
// 进入拖拽状态
|
|
16197
|
+
const index = idx;
|
|
16198
|
+
hasStartedDragViaLongPressRef.current = true;
|
|
16199
|
+
// 启动与 mouseDown 相同的拖拽逻辑
|
|
16200
|
+
setDragState({
|
|
16201
|
+
isDragging: true,
|
|
16202
|
+
dragIndex: index,
|
|
16203
|
+
originalPosition: [...coordinates[index]],
|
|
16204
|
+
currentPosition: [...coordinates[index]],
|
|
16205
|
+
newVertexIndex: -1,
|
|
16206
|
+
edgeInfo: null,
|
|
16207
|
+
dragType: 'existing',
|
|
16208
|
+
});
|
|
16209
|
+
}
|
|
16210
|
+
}
|
|
16211
|
+
}, [platform, dragState.isDragging, coordinates, selectedVertexIndex]);
|
|
16047
16212
|
// 结束拖拽
|
|
16048
16213
|
const handleMouseUp = React.useCallback(() => {
|
|
16049
16214
|
console.log('handleMouseUp', JSON.stringify(dragState));
|
|
@@ -16099,9 +16264,12 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16099
16264
|
},
|
|
16100
16265
|
}, platform);
|
|
16101
16266
|
document.body.style.userSelect = 'none';
|
|
16267
|
+
// 禁止系统滚动和浏览器触摸手势,防止底层地图跟随移动
|
|
16268
|
+
document.body.style.touchAction = 'none';
|
|
16102
16269
|
return () => {
|
|
16103
16270
|
cleanup();
|
|
16104
16271
|
document.body.style.userSelect = '';
|
|
16272
|
+
document.body.style.touchAction = '';
|
|
16105
16273
|
};
|
|
16106
16274
|
}
|
|
16107
16275
|
else {
|
|
@@ -16166,6 +16334,45 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16166
16334
|
const ghostFirstMidpoint = createMode && mousePos && !completed && renderCoordinates.length >= 1
|
|
16167
16335
|
? calculateMidpoint(renderCoordinates[0], [mousePos.x, mousePos.y])
|
|
16168
16336
|
: null;
|
|
16337
|
+
// H5平台处理触摸双击
|
|
16338
|
+
const handleVertexDoubleTap = React.useCallback((index) => {
|
|
16339
|
+
const now = Date.now();
|
|
16340
|
+
const timeDelta = now - lastTapRef.current;
|
|
16341
|
+
// 检查是否为双击(300ms内,且是同一个点)
|
|
16342
|
+
if (timeDelta < DOUBLE_TAP_DELAY && lastTapIndexRef.current === index) {
|
|
16343
|
+
// 只有在选中点的情况下才允许删除
|
|
16344
|
+
if (selectedVertexIndex === index && onVertexDelete && coordinates.length > 3) {
|
|
16345
|
+
// 将渲染索引转换为原始points的索引
|
|
16346
|
+
onVertexDelete(renderCoordinates?.length - 1 - index);
|
|
16347
|
+
// 删除后立即取消拖拽状态,避免误触发拖动
|
|
16348
|
+
setDragState({
|
|
16349
|
+
isDragging: false,
|
|
16350
|
+
dragIndex: -1,
|
|
16351
|
+
originalPosition: null,
|
|
16352
|
+
currentPosition: null,
|
|
16353
|
+
newVertexIndex: -1,
|
|
16354
|
+
edgeInfo: null,
|
|
16355
|
+
dragType: null,
|
|
16356
|
+
});
|
|
16357
|
+
// 删除后取消选中状态
|
|
16358
|
+
setSelectedVertexIndex(-1);
|
|
16359
|
+
}
|
|
16360
|
+
// 重置点击时间
|
|
16361
|
+
lastTapRef.current = 0;
|
|
16362
|
+
lastTapIndexRef.current = -1;
|
|
16363
|
+
}
|
|
16364
|
+
else {
|
|
16365
|
+
// 记录本次点击
|
|
16366
|
+
lastTapRef.current = now;
|
|
16367
|
+
lastTapIndexRef.current = index;
|
|
16368
|
+
}
|
|
16369
|
+
}, [
|
|
16370
|
+
selectedVertexIndex,
|
|
16371
|
+
onVertexDelete,
|
|
16372
|
+
coordinates?.length,
|
|
16373
|
+
editMapInfo?.createMode,
|
|
16374
|
+
renderCoordinates?.length,
|
|
16375
|
+
]);
|
|
16169
16376
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(editMode || (createMode && completed)) &&
|
|
16170
16377
|
dragState.isDragging &&
|
|
16171
16378
|
dragState.dragType !== 'new' &&
|
|
@@ -16174,7 +16381,7 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16174
16381
|
const prevIndex = (dragState.dragIndex - 1 + coordinates.length) % coordinates.length;
|
|
16175
16382
|
const nextIndex = (dragState.dragIndex + 1) % coordinates.length;
|
|
16176
16383
|
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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" }), jsxRuntime.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" })] }));
|
|
16177
|
-
})()] })), renderCoordinates.length >= 3 && (jsxRuntime.jsx("polygon", { className:
|
|
16384
|
+
})()] })), renderCoordinates.length >= 3 && (jsxRuntime.jsx("polygon", { className: styles$2.polygonPathG, points: polygonPoints, fill: fillColor, fillOpacity: fillOpacity, stroke: "none" // 边框透明
|
|
16178
16385
|
, onClick: onPolygonClick })), jsxRuntime.jsxs("g", { className: styles$2.polygonPathG, children: [renderCoordinates.length >= 2 &&
|
|
16179
16386
|
pathSegments.map((segment, index) => {
|
|
16180
16387
|
if (segment.points.length < 2)
|
|
@@ -16192,9 +16399,16 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16192
16399
|
renderCoordinates.map((coord, index) => {
|
|
16193
16400
|
const nextCoord = renderCoordinates[(index + 1) % renderCoordinates.length];
|
|
16194
16401
|
const isDashPath = coord[2] === 1;
|
|
16195
|
-
return (jsxRuntime.jsx("line", { x1: coord[0], y1: coord[1], x2: nextCoord[0], y2: nextCoord[1], stroke: isDashPath ? 'transparent' : strokeColor, strokeWidth: strokeWidth, className: styles$2.addVertex,
|
|
16402
|
+
return (jsxRuntime.jsx("line", { x1: coord[0], y1: coord[1], x2: nextCoord[0], y2: nextCoord[1], stroke: isDashPath ? 'transparent' : strokeColor, strokeWidth: platform === exports.PlatformType.H5 ? strokeWidth * 3 : strokeWidth, className: styles$2.addVertex, style: {
|
|
16403
|
+
userSelect: 'none',
|
|
16404
|
+
WebkitUserSelect: 'none',
|
|
16405
|
+
WebkitTouchCallout: 'none',
|
|
16406
|
+
touchAction: 'none',
|
|
16407
|
+
}, vectorEffect: "non-scaling-stroke", ...(platform === exports.PlatformType.H5
|
|
16196
16408
|
? {
|
|
16197
|
-
onTouchStart: createReactEventHandler((e) =>
|
|
16409
|
+
onTouchStart: createReactEventHandler((e) => handleEdgeLongPressStart(e, index)),
|
|
16410
|
+
onTouchEnd: createReactEventHandler(() => handleEdgeLongPressEnd()),
|
|
16411
|
+
onTouchCancel: createReactEventHandler(() => handleEdgeLongPressEnd()),
|
|
16198
16412
|
}
|
|
16199
16413
|
: {
|
|
16200
16414
|
onMouseDown: (e) => handleEdgeClick(e, index),
|
|
@@ -16217,14 +16431,27 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16217
16431
|
setHoverVertex(null);
|
|
16218
16432
|
},
|
|
16219
16433
|
}) }, `edge-${index}`));
|
|
16220
|
-
}), ghostLastPath && (jsxRuntime.jsx("path", { d: ghostLastPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), ghostFirstPath && renderCoordinates.length >= 2 && (jsxRuntime.jsx("path", { d: ghostFirstPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), jsxRuntime.jsx(DragDistanceIndicator, { dragState: dragState, strokeColor: strokeColor, editMode: editMode, createMode: createMode, completed: completed, fontSize: 30 * overlayScale }), jsxRuntime.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 && (jsxRuntime.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)) &&
|
|
16434
|
+
}), ghostLastPath && (jsxRuntime.jsx("path", { d: ghostLastPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), ghostFirstPath && renderCoordinates.length >= 2 && (jsxRuntime.jsx("path", { d: ghostFirstPath, stroke: strokeColor, strokeWidth: strokeWidth, vectorEffect: "non-scaling-stroke", opacity: 0.7, onClick: onPathClick })), jsxRuntime.jsx(DragDistanceIndicator, { dragState: dragState, strokeColor: strokeColor, editMode: editMode, createMode: createMode, completed: completed, fontSize: platform === exports.PlatformType.H5 ? 12 * overlayScale : 30 * overlayScale }), jsxRuntime.jsx(DistanceLabels, { coordinates: renderCoordinates, createMode: createMode, editMode: editMode, completed: completed, showPoints: showPoints, mousePos: mousePos, ghostLastDistance: ghostLastDistance, ghostLastMidpoint: ghostLastMidpoint, ghostFirstDistance: ghostFirstDistance, ghostFirstMidpoint: ghostFirstMidpoint, fontSize: platform === exports.PlatformType.H5 ? 12 * overlayScale : 30 * overlayScale, showFirstDistance: platform !== exports.PlatformType.H5 }), hoverVertex && !dragState.isDragging && (jsxRuntime.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)) &&
|
|
16221
16435
|
renderCoordinates.map((coord, idx) => {
|
|
16222
16436
|
// 判断当前顶点的状态
|
|
16223
16437
|
const isLastPoint = idx === renderCoordinates.length - 1;
|
|
16224
16438
|
const canComplete = createMode && !completed && renderCoordinates.length >= 3 && isLastPoint;
|
|
16225
16439
|
const isCreatedAndCanDrag = createMode && completed; // 创建完成后可拖拽
|
|
16226
16440
|
const isInEditMode = editMode;
|
|
16227
|
-
|
|
16441
|
+
// H5模式下选中的顶点显示蓝色,并且放大1.5倍
|
|
16442
|
+
const isSelected = platform === exports.PlatformType.H5 && selectedVertexIndex === idx;
|
|
16443
|
+
const vertexRadius = isSelected ? (canComplete ? 16 : 12) * 1.2 : canComplete ? 16 : 12;
|
|
16444
|
+
const vertexFill = isSelected ? '#FFAB7E' : 'white';
|
|
16445
|
+
return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx(VertexElement, { className: generateVertexClassName, style: {
|
|
16446
|
+
userSelect: 'none',
|
|
16447
|
+
WebkitUserSelect: 'none',
|
|
16448
|
+
WebkitTouchCallout: 'none',
|
|
16449
|
+
touchAction: 'none',
|
|
16450
|
+
}, stroke: strokeColor, fill: vertexFill, cx: coord[0], cy: coord[1], r: vertexRadius, onClick: (e) => handleVertexClick(e, idx), onDoubleClick: (e) => {
|
|
16451
|
+
console.log('双击事件', selectedVertexIndex, idx);
|
|
16452
|
+
if (platform === exports.PlatformType.H5) {
|
|
16453
|
+
return;
|
|
16454
|
+
}
|
|
16228
16455
|
// 阻止双击事件冒泡到Google Maps
|
|
16229
16456
|
e.preventDefault();
|
|
16230
16457
|
e.stopPropagation();
|
|
@@ -16242,12 +16469,6 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16242
16469
|
setTimeout(() => {
|
|
16243
16470
|
isDoubleClickingRef.current = false;
|
|
16244
16471
|
}, 300);
|
|
16245
|
-
if (platform === exports.PlatformType.H5) {
|
|
16246
|
-
if (onVertexDelete && coordinates.length > 3) {
|
|
16247
|
-
onVertexDelete(idx);
|
|
16248
|
-
}
|
|
16249
|
-
return;
|
|
16250
|
-
}
|
|
16251
16472
|
// 打开删除确认 Tooltip(仅在可编辑时)
|
|
16252
16473
|
if (editMode || (createMode && completed)) {
|
|
16253
16474
|
setTooltipIndex(idx);
|
|
@@ -16255,12 +16476,51 @@ const PolygonElement = ({ points, fillColor = 'rgba(0, 0, 0, 0.1)', fillOpacity
|
|
|
16255
16476
|
}, ...(platform === exports.PlatformType.H5
|
|
16256
16477
|
? {
|
|
16257
16478
|
onTouchStart: createReactEventHandler((e) => {
|
|
16258
|
-
|
|
16259
|
-
|
|
16260
|
-
|
|
16261
|
-
|
|
16262
|
-
|
|
16479
|
+
e.preventDefault();
|
|
16480
|
+
e.stopPropagation();
|
|
16481
|
+
// 如果不是支持拖拽的话,则不往下走
|
|
16482
|
+
if (!draggable) {
|
|
16483
|
+
return;
|
|
16484
|
+
}
|
|
16485
|
+
// 如果未选中,则走长按选中逻辑
|
|
16486
|
+
if (selectedVertexIndex !== idx) {
|
|
16487
|
+
handleVertexLongPressStart(e, idx);
|
|
16488
|
+
}
|
|
16489
|
+
else {
|
|
16490
|
+
// 已选中:准备可能的拖拽(记录起点),不阻塞双击
|
|
16491
|
+
touchStartPosRef.current = {
|
|
16492
|
+
x: e.clientX,
|
|
16493
|
+
y: e.clientY,
|
|
16494
|
+
};
|
|
16495
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16496
|
+
isVertexLongPressedRef.current = false;
|
|
16497
|
+
longPressVertexIndexRef.current = idx;
|
|
16498
|
+
}
|
|
16499
|
+
}),
|
|
16500
|
+
onTouchMove: createReactEventHandler((e) => {
|
|
16501
|
+
// 如果不是支持拖拽的话,则不往下走
|
|
16502
|
+
if (!draggable) {
|
|
16503
|
+
return;
|
|
16504
|
+
}
|
|
16505
|
+
// 长按后,超过阈值再进入拖拽
|
|
16506
|
+
handleVertexTouchMoveMaybeStartDrag(e, idx);
|
|
16507
|
+
}),
|
|
16508
|
+
onTouchEnd: createReactEventHandler(() => {
|
|
16509
|
+
// 如果不是支持拖拽的话,则不往下走
|
|
16510
|
+
if (!draggable) {
|
|
16511
|
+
return;
|
|
16263
16512
|
}
|
|
16513
|
+
// 如果已经通过长按进入拖拽,不触发双击检测
|
|
16514
|
+
const startedDrag = hasStartedDragViaLongPressRef.current;
|
|
16515
|
+
handleVertexLongPressEnd();
|
|
16516
|
+
if (!startedDrag && !isVertexLongPressedRef.current) {
|
|
16517
|
+
handleVertexDoubleTap(idx);
|
|
16518
|
+
}
|
|
16519
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16520
|
+
}),
|
|
16521
|
+
onTouchCancel: createReactEventHandler(() => {
|
|
16522
|
+
handleVertexLongPressEnd();
|
|
16523
|
+
hasStartedDragViaLongPressRef.current = false;
|
|
16264
16524
|
}),
|
|
16265
16525
|
}
|
|
16266
16526
|
: {
|
|
@@ -16333,19 +16593,26 @@ const BoundaryElement = ({ data }) => {
|
|
|
16333
16593
|
* 点击边界的回调
|
|
16334
16594
|
*/
|
|
16335
16595
|
const onPathClick = React.useCallback(() => {
|
|
16336
|
-
onSelectElement?.(exports.DataType.BOUNDARY);
|
|
16596
|
+
onSelectElement?.(exports.DataType.BOUNDARY, data);
|
|
16337
16597
|
if (platform === exports.PlatformType.H5) {
|
|
16338
16598
|
// 对于地块来说,如果当前有元素是在编辑和创建模式下,则不进行选中
|
|
16339
16599
|
if (editMapInfo.mobileMode === exports.MobileEditMode.EDIT ||
|
|
16340
16600
|
editMapInfo.mobileMode === exports.MobileEditMode.CREATE) {
|
|
16341
16601
|
return;
|
|
16342
16602
|
}
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
|
|
16347
|
-
|
|
16348
|
-
|
|
16603
|
+
if (editMapInfo.selectElement?.id === data.id) {
|
|
16604
|
+
setEditMapInfo({
|
|
16605
|
+
...INIT_EDIT_MAP_INFO,
|
|
16606
|
+
});
|
|
16607
|
+
}
|
|
16608
|
+
else {
|
|
16609
|
+
setEditMapInfo((prev) => ({
|
|
16610
|
+
...prev,
|
|
16611
|
+
mobileMode: exports.MobileEditMode.START,
|
|
16612
|
+
elementType: exports.DataType.BOUNDARY,
|
|
16613
|
+
selectElement: data,
|
|
16614
|
+
}));
|
|
16615
|
+
}
|
|
16349
16616
|
}
|
|
16350
16617
|
else {
|
|
16351
16618
|
if (editMapInfo?.selectElement)
|
|
@@ -16358,7 +16625,9 @@ const BoundaryElement = ({ data }) => {
|
|
|
16358
16625
|
}));
|
|
16359
16626
|
}
|
|
16360
16627
|
}, [platform, data, editMapInfo]);
|
|
16361
|
-
return (jsxRuntime.jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: onPathClick,
|
|
16628
|
+
return (jsxRuntime.jsx(PolygonElement, { points: currentPoints, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: onPathClick, onPolygonClick: () => {
|
|
16629
|
+
onPathClick();
|
|
16630
|
+
}, onCoordinatesChange: (coordinates) => {
|
|
16362
16631
|
console.log('onCoordinatesChange', coordinates);
|
|
16363
16632
|
setEditMapInfo((prev) => ({
|
|
16364
16633
|
...prev,
|
|
@@ -16474,31 +16743,32 @@ const useHistoryHandle = (props) => {
|
|
|
16474
16743
|
|
|
16475
16744
|
const ObstacleElement = ({ data }) => {
|
|
16476
16745
|
const style = data.style || {};
|
|
16477
|
-
const { editMapInfo, setEditMapInfo, onHandleEnterRecord } = useMapEditContext();
|
|
16746
|
+
const { editMapInfo, setEditMapInfo, onHandleEnterRecord, onSelectElement } = useMapEditContext();
|
|
16478
16747
|
const { platform } = useCommonContext();
|
|
16479
16748
|
const { disabledObstacles } = useSvgEditContext();
|
|
16480
16749
|
const { addHistory } = useHistoryHandle();
|
|
16481
16750
|
// 处理删除顶点
|
|
16482
16751
|
const handleCreateVertexDelete = React.useCallback((vertexIndex) => {
|
|
16752
|
+
console.log('ObstacleElement删除顶点', vertexIndex);
|
|
16483
16753
|
if (editMapInfo?.selectElement?.points && editMapInfo?.selectElement?.points?.length > 0) {
|
|
16484
16754
|
const newPoints = editMapInfo?.selectElement?.points?.filter((_, index) => index !== vertexIndex);
|
|
16755
|
+
console.log('newPoints', newPoints);
|
|
16485
16756
|
setEditMapInfo((prev) => ({
|
|
16486
16757
|
...prev,
|
|
16487
16758
|
selectElement: {
|
|
16488
16759
|
...prev.selectElement,
|
|
16489
|
-
points: newPoints,
|
|
16760
|
+
points: [...newPoints],
|
|
16490
16761
|
},
|
|
16491
16762
|
}));
|
|
16492
16763
|
addHistory({
|
|
16493
16764
|
selectElement: {
|
|
16494
16765
|
...editMapInfo.selectElement,
|
|
16495
|
-
points: newPoints,
|
|
16766
|
+
points: [...newPoints],
|
|
16496
16767
|
},
|
|
16497
16768
|
});
|
|
16498
16769
|
}
|
|
16499
16770
|
}, [editMapInfo]);
|
|
16500
16771
|
const currentPoints = React.useMemo(() => {
|
|
16501
|
-
// 为了方便解决删除顶点的时候,delete icon被遮挡的问题,所以逆序一下
|
|
16502
16772
|
if (editMapInfo?.selectElement?.id === data.id) {
|
|
16503
16773
|
return editMapInfo.selectElement.points;
|
|
16504
16774
|
}
|
|
@@ -16518,41 +16788,28 @@ const ObstacleElement = ({ data }) => {
|
|
|
16518
16788
|
return dp2px(style.lineWidth || 3);
|
|
16519
16789
|
}, [platform, style, editMapInfo]);
|
|
16520
16790
|
const onPathClick = React.useCallback(() => {
|
|
16791
|
+
onSelectElement?.(exports.DataType.OBSTACLE, data);
|
|
16521
16792
|
if (platform === exports.PlatformType.H5) {
|
|
16522
16793
|
// h5编辑模式下,禁区只有在start模式下才需要选中
|
|
16523
16794
|
if (editMapInfo.mobileMode === exports.MobileEditMode.EDIT ||
|
|
16524
16795
|
editMapInfo.mobileMode === exports.MobileEditMode.CREATE) {
|
|
16525
16796
|
return;
|
|
16526
16797
|
}
|
|
16527
|
-
|
|
16528
|
-
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
|
|
16532
|
-
|
|
16533
|
-
|
|
16798
|
+
if (editMapInfo.selectElement?.id === data.id) {
|
|
16799
|
+
setEditMapInfo({
|
|
16800
|
+
...INIT_EDIT_MAP_INFO,
|
|
16801
|
+
});
|
|
16802
|
+
}
|
|
16803
|
+
else {
|
|
16804
|
+
setEditMapInfo((prev) => ({
|
|
16805
|
+
...prev,
|
|
16806
|
+
mobileMode: exports.MobileEditMode.START,
|
|
16807
|
+
elementType: exports.DataType.OBSTACLE,
|
|
16808
|
+
selectElement: data,
|
|
16809
|
+
}));
|
|
16810
|
+
}
|
|
16534
16811
|
}
|
|
16535
|
-
|
|
16536
|
-
return;
|
|
16537
|
-
onHandleEnterRecord?.({
|
|
16538
|
-
type: 3,
|
|
16539
|
-
function: 1,
|
|
16540
|
-
zoneId: data.id,
|
|
16541
|
-
})?.then(() => {
|
|
16542
|
-
setEditMapInfo((prev) => ({
|
|
16543
|
-
...prev,
|
|
16544
|
-
selectElement: data,
|
|
16545
|
-
historyList: [
|
|
16546
|
-
{
|
|
16547
|
-
selectElement: data,
|
|
16548
|
-
},
|
|
16549
|
-
],
|
|
16550
|
-
currentHistoryIndex: 0,
|
|
16551
|
-
elementType: exports.DataType.OBSTACLE,
|
|
16552
|
-
editMap: true,
|
|
16553
|
-
}));
|
|
16554
|
-
});
|
|
16555
|
-
}, [disabledObstacles, data, onHandleEnterRecord, editMapInfo]);
|
|
16812
|
+
}, [data, editMapInfo, onSelectElement]);
|
|
16556
16813
|
const editMode = React.useMemo(() => {
|
|
16557
16814
|
if (platform === exports.PlatformType.H5) {
|
|
16558
16815
|
return (editMapInfo?.mobileMode === exports.MobileEditMode.EDIT &&
|
|
@@ -16561,10 +16818,9 @@ const ObstacleElement = ({ data }) => {
|
|
|
16561
16818
|
return editMapInfo?.selectElement?.id === data.id;
|
|
16562
16819
|
}, [editMapInfo, data, platform]);
|
|
16563
16820
|
return (jsxRuntime.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: () => {
|
|
16564
|
-
|
|
16565
|
-
onPathClick();
|
|
16566
|
-
}
|
|
16821
|
+
onPathClick();
|
|
16567
16822
|
}, onVertexDelete: (vertexIndex) => handleCreateVertexDelete(vertexIndex), onCoordinatesChange: (coordinates) => {
|
|
16823
|
+
console.log('onCoordinatesChange', coordinates);
|
|
16568
16824
|
if (platform === exports.PlatformType.H5 && editMapInfo.mobileMode === exports.MobileEditMode.CREATE) {
|
|
16569
16825
|
return;
|
|
16570
16826
|
}
|
|
@@ -17268,9 +17524,7 @@ const VisionOffTransformWrapper = ({ data, isSelected = false, onSelect, onCance
|
|
|
17268
17524
|
return (jsxRuntime.jsxs("g", { ref: containerRef, className: `vision-off-transform-wrapper ${className} ${isSelected ? 'selected' : ''}`, "data-transform-wrapper": "true", children: [jsxRuntime.jsx(PolygonElement, { points: visionOffData?.points, fillColor: style.fillColor, fillOpacity: style.fillOpacity, strokeColor: style.lineColor, strokeWidth: strokeWidth, editMode: false, onPathClick: () => {
|
|
17269
17525
|
onSelect?.();
|
|
17270
17526
|
}, onPolygonClick: () => {
|
|
17271
|
-
|
|
17272
|
-
onSelect?.();
|
|
17273
|
-
}
|
|
17527
|
+
onSelect?.();
|
|
17274
17528
|
} }), isSelected && currentPoints.length === 4 && (jsxRuntime.jsx("polygon", { points: currentPoints.map((point) => `${point.x},${point.y}`).join(' '), fill: "transparent", stroke: "none", style: { cursor: 'move' }, ...(platform === exports.PlatformType.H5
|
|
17275
17529
|
? {
|
|
17276
17530
|
onTouchStart: createReactEventHandler((e) => {
|
|
@@ -17352,7 +17606,7 @@ const VisionOffTransformWrapper = ({ data, isSelected = false, onSelect, onCance
|
|
|
17352
17606
|
};
|
|
17353
17607
|
|
|
17354
17608
|
const VisionOffElement = ({ data, onSelect }) => {
|
|
17355
|
-
const { setEditMapInfo, onHandleEnterRecord, editMapInfo } = useMapEditContext();
|
|
17609
|
+
const { setEditMapInfo, onHandleEnterRecord, editMapInfo, onSelectElement } = useMapEditContext();
|
|
17356
17610
|
const { addHistory } = useHistoryHandle();
|
|
17357
17611
|
const { platform } = useCommonContext();
|
|
17358
17612
|
const isSelected = React.useMemo(() => {
|
|
@@ -17365,18 +17619,16 @@ const VisionOffElement = ({ data, onSelect }) => {
|
|
|
17365
17619
|
return editMapInfo?.selectElement?.id === data.id;
|
|
17366
17620
|
}, [editMapInfo, data, platform]);
|
|
17367
17621
|
const handleSelect = React.useCallback(() => {
|
|
17622
|
+
onSelectElement?.(exports.DataType.VISION_OFF, data);
|
|
17368
17623
|
if (platform === exports.PlatformType.H5) {
|
|
17369
17624
|
// h5编辑模式下,
|
|
17370
17625
|
// start模式可以任意选
|
|
17371
|
-
// create或者是edit模式的话,只有选中的是visionOff
|
|
17372
|
-
if (
|
|
17373
|
-
editMapInfo.mobileMode === exports.MobileEditMode.EDIT)
|
|
17374
|
-
editMapInfo.elementType !== exports.DataType.VISION_OFF) {
|
|
17375
|
-
|
|
17376
|
-
|
|
17377
|
-
if ((editMapInfo.mobileMode === exports.MobileEditMode.CREATE ||
|
|
17378
|
-
editMapInfo.mobileMode === exports.MobileEditMode.EDIT) &&
|
|
17379
|
-
editMapInfo.elementType === exports.DataType.VISION_OFF) {
|
|
17626
|
+
// create或者是edit模式的话,只有选中的是visionOff的时候才能操作
|
|
17627
|
+
if (editMapInfo.mobileMode === exports.MobileEditMode.CREATE ||
|
|
17628
|
+
editMapInfo.mobileMode === exports.MobileEditMode.EDIT) {
|
|
17629
|
+
if (editMapInfo.elementType !== exports.DataType.VISION_OFF) {
|
|
17630
|
+
return;
|
|
17631
|
+
}
|
|
17380
17632
|
setEditMapInfo((prev) => ({
|
|
17381
17633
|
...prev,
|
|
17382
17634
|
selectElement: data,
|
|
@@ -17385,36 +17637,43 @@ const VisionOffElement = ({ data, onSelect }) => {
|
|
|
17385
17637
|
}));
|
|
17386
17638
|
return;
|
|
17387
17639
|
}
|
|
17388
|
-
|
|
17389
|
-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
|
|
17393
|
-
|
|
17640
|
+
if (editMapInfo.selectElement?.id === data.id) {
|
|
17641
|
+
setEditMapInfo({
|
|
17642
|
+
...INIT_EDIT_MAP_INFO,
|
|
17643
|
+
});
|
|
17644
|
+
}
|
|
17645
|
+
else {
|
|
17646
|
+
setEditMapInfo((prev) => ({
|
|
17647
|
+
...prev,
|
|
17648
|
+
selectElement: data,
|
|
17649
|
+
elementType: exports.DataType.VISION_OFF,
|
|
17650
|
+
mobileMode: exports.MobileEditMode.START,
|
|
17651
|
+
}));
|
|
17652
|
+
}
|
|
17394
17653
|
return;
|
|
17395
17654
|
}
|
|
17396
17655
|
if (editMapInfo?.selectElement)
|
|
17397
17656
|
return;
|
|
17398
|
-
return onHandleEnterRecord?.({
|
|
17399
|
-
|
|
17400
|
-
|
|
17401
|
-
})?.then(() => {
|
|
17402
|
-
|
|
17403
|
-
|
|
17404
|
-
|
|
17405
|
-
|
|
17406
|
-
|
|
17407
|
-
|
|
17408
|
-
|
|
17409
|
-
|
|
17410
|
-
|
|
17411
|
-
|
|
17412
|
-
|
|
17413
|
-
|
|
17414
|
-
|
|
17415
|
-
|
|
17416
|
-
});
|
|
17417
|
-
}, [data, onHandleEnterRecord, platform, editMapInfo]);
|
|
17657
|
+
// return onHandleEnterRecord?.({
|
|
17658
|
+
// type: 2,
|
|
17659
|
+
// function: 1,
|
|
17660
|
+
// })?.then(() => {
|
|
17661
|
+
// onSelect?.();
|
|
17662
|
+
// setEditMapInfo((prev: EditMapInfo) => ({
|
|
17663
|
+
// ...prev,
|
|
17664
|
+
// selectElement: data,
|
|
17665
|
+
// elementType: DataType.VISION_OFF,
|
|
17666
|
+
// historyList: [
|
|
17667
|
+
// {
|
|
17668
|
+
// selectElement: data,
|
|
17669
|
+
// },
|
|
17670
|
+
// ],
|
|
17671
|
+
// currentHistoryIndex: 0,
|
|
17672
|
+
// editMap: true,
|
|
17673
|
+
// isShowDrag: true,
|
|
17674
|
+
// }));
|
|
17675
|
+
// });
|
|
17676
|
+
}, [data, onHandleEnterRecord, platform, editMapInfo, onSelectElement]);
|
|
17418
17677
|
const onCancel = React.useCallback(() => {
|
|
17419
17678
|
if (platform === exports.PlatformType.H5) {
|
|
17420
17679
|
// 在h5中,这里的取消其实对应的是删除元素
|
|
@@ -17902,7 +18161,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
|
|
|
17902
18161
|
}, [data]);
|
|
17903
18162
|
const remainingTime = React.useMemo(() => {
|
|
17904
18163
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
17905
|
-
console.log('data.expiration_ts--', data.expiration_ts);
|
|
18164
|
+
// console.log('data.expiration_ts--', data.expiration_ts);
|
|
17906
18165
|
if (data.expiration_ts <= currentTime) {
|
|
17907
18166
|
return 0;
|
|
17908
18167
|
}
|
|
@@ -18147,7 +18406,7 @@ const DoodleTransformWrapper = ({ data, isSelected = false, isSelectedWithoutOpe
|
|
|
18147
18406
|
};
|
|
18148
18407
|
|
|
18149
18408
|
const DoodleElement = ({ data }) => {
|
|
18150
|
-
const { editMapInfo, setEditMapInfo,
|
|
18409
|
+
const { editMapInfo, setEditMapInfo, onHandleEvent, onSelectElement } = useMapEditContext();
|
|
18151
18410
|
const { addHistory } = useHistoryHandle();
|
|
18152
18411
|
const { platform, doodleList } = useCommonContext();
|
|
18153
18412
|
const isSelected = React.useMemo(() => {
|
|
@@ -18196,6 +18455,7 @@ const DoodleElement = ({ data }) => {
|
|
|
18196
18455
|
}, [data]);
|
|
18197
18456
|
const handleTransformChange = (transform) => { };
|
|
18198
18457
|
const handleSelect = React.useCallback(() => {
|
|
18458
|
+
onSelectElement?.(exports.DataType.DOODLE, data);
|
|
18199
18459
|
if (platform === exports.PlatformType.H5) {
|
|
18200
18460
|
// h5编辑模式下,
|
|
18201
18461
|
// 如果是创建,只能选择新建的doodle
|
|
@@ -18203,7 +18463,7 @@ const DoodleElement = ({ data }) => {
|
|
|
18203
18463
|
editMapInfo.mobileMode === exports.MobileEditMode.EDIT) {
|
|
18204
18464
|
return;
|
|
18205
18465
|
}
|
|
18206
|
-
//
|
|
18466
|
+
// 如果start模式下
|
|
18207
18467
|
setEditMapInfo((prev) => ({
|
|
18208
18468
|
...prev,
|
|
18209
18469
|
selectElement: data,
|
|
@@ -18212,34 +18472,29 @@ const DoodleElement = ({ data }) => {
|
|
|
18212
18472
|
}));
|
|
18213
18473
|
return;
|
|
18214
18474
|
}
|
|
18215
|
-
if (editMapInfo?.selectElement) {
|
|
18216
|
-
|
|
18217
|
-
}
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
editMap: true,
|
|
18239
|
-
isShowDrag: true,
|
|
18240
|
-
}));
|
|
18241
|
-
});
|
|
18242
|
-
}, [data, onHandleEnterRecord, platform, editMapInfo]);
|
|
18475
|
+
// if (editMapInfo?.selectElement) {
|
|
18476
|
+
// return;
|
|
18477
|
+
// }
|
|
18478
|
+
// setEditMapInfo((prev: EditMapInfo) => ({
|
|
18479
|
+
// ...prev,
|
|
18480
|
+
// historyList: [
|
|
18481
|
+
// {
|
|
18482
|
+
// selectElement: {
|
|
18483
|
+
// ...data,
|
|
18484
|
+
// transformedPoints: transformedElements,
|
|
18485
|
+
// },
|
|
18486
|
+
// },
|
|
18487
|
+
// ],
|
|
18488
|
+
// currentHistoryIndex: 0,
|
|
18489
|
+
// selectElement: {
|
|
18490
|
+
// ...data,
|
|
18491
|
+
// transformedPoints: transformedElements,
|
|
18492
|
+
// },
|
|
18493
|
+
// elementType: DataType.DOODLE,
|
|
18494
|
+
// editMap: true,
|
|
18495
|
+
// isShowDrag: true,
|
|
18496
|
+
// }));
|
|
18497
|
+
}, [data, platform, editMapInfo, onSelectElement]);
|
|
18243
18498
|
const handleCancel = React.useCallback(() => {
|
|
18244
18499
|
if (platform === exports.PlatformType.H5) {
|
|
18245
18500
|
setEditMapInfo((prev) => ({
|
|
@@ -18289,7 +18544,6 @@ const DoodleElement = ({ data }) => {
|
|
|
18289
18544
|
},
|
|
18290
18545
|
});
|
|
18291
18546
|
}, [transformedElements]);
|
|
18292
|
-
console.log('isSelectedWithoutOperation--->', editMapInfo, isSelectedWithoutOperation, isSelected);
|
|
18293
18547
|
return (jsxRuntime.jsx(DoodleTransformWrapper, { data: originData, onTransformChange: handleTransformChange, isSelected: isSelected, isSelectedWithoutOperation: isSelectedWithoutOperation, onSelect: handleSelect, onCancel: handleCancel, onDragEnd: handleDragEnd, showInfo: platform === exports.PlatformType.H5, onClickInfo: handleClickInfo, minScale: minScale }));
|
|
18294
18548
|
};
|
|
18295
18549
|
|
|
@@ -19333,7 +19587,7 @@ function usePolygonDrawing(options = {}) {
|
|
|
19333
19587
|
const { checkCanNotCreateAtPosition } = useCheckElement();
|
|
19334
19588
|
const { addHistory } = useHistoryHandle();
|
|
19335
19589
|
const points = React.useMemo(() => {
|
|
19336
|
-
console.log('points->', editMapInfo?.selectElement?.points);
|
|
19590
|
+
// console.log('points->', editMapInfo?.selectElement?.points);
|
|
19337
19591
|
return editMapInfo?.selectElement?.points?.map((item) => ({ x: item[0], y: item[1] })) || [];
|
|
19338
19592
|
}, [editMapInfo?.selectElement?.points]);
|
|
19339
19593
|
const completed = React.useMemo(() => {
|
|
@@ -20477,13 +20731,6 @@ modelType, mapRef, mapJson, pathJson, realTimeData, antennaConfig, onMapLoad, on
|
|
|
20477
20731
|
const scale = Math.pow(2, -zoomDiff); // 负数实现反向缩放
|
|
20478
20732
|
console.log('scale', scale, currentZoom, zoomDiff);
|
|
20479
20733
|
setOverlayScale(scale < 1 ? 1 : scale);
|
|
20480
|
-
// if (scale < 1) {
|
|
20481
|
-
// setOverlayScale(1);
|
|
20482
|
-
// } else if (scale > 4) {
|
|
20483
|
-
// setOverlayScale(4);
|
|
20484
|
-
// } else {
|
|
20485
|
-
// setOverlayScale(scale);
|
|
20486
|
-
// }
|
|
20487
20734
|
};
|
|
20488
20735
|
// 使用lodash throttle进行节流处理: 100ms内只执行一次
|
|
20489
20736
|
const handleZoomChanged = throttle$2(updateScale, 50);
|