From 0915529af06d8702c6ed9ed7e128ca013f01b932 Mon Sep 17 00:00:00 2001 From: huaqiang Date: Wed, 12 Aug 2026 11:15:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(map):=20=E6=BB=9A=E8=BD=AE=E7=BC=A9?= =?UTF-8?q?=E6=94=BE=E4=BB=A5=E5=85=89=E6=A0=87=E4=B8=BA=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E5=B9=B6=E8=B0=83=E6=95=B4=E4=BF=9D=E5=AD=98=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/EquipmentManagementPage.vue | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/views/dashboard1/pages/EquipmentManagementPage.vue b/src/views/dashboard1/pages/EquipmentManagementPage.vue index 53abbf0..063b075 100644 --- a/src/views/dashboard1/pages/EquipmentManagementPage.vue +++ b/src/views/dashboard1/pages/EquipmentManagementPage.vue @@ -557,7 +557,7 @@ function markCurrentMapUploaded(payload: Partial) { currentConfig.value.lastSyncedAt = nowString(); } -// 调用小车地图地址接口,在保存下发时单独保存 PGM 和 YAML 文件 URL +// 调用小车地图地址接口,在保存时单独保存 PGM 和 YAML 文件 URL async function saveCurrentMapUrls() { if (!currentConfiguredDevice.value || !currentConfig.value) { return; @@ -717,7 +717,7 @@ async function handleMapImageFileChange(event: Event) { rosMapMeta.imageUrl = uploadedUrl; markCurrentMapUploaded({ imageUrl: uploadedUrl, name: file.name }); - mapUploadMessage.value = "地图 PGM 上传成功,保存下发后生效"; + mapUploadMessage.value = "地图 PGM 上传成功,保存后生效"; } catch (error) { console.error(error); mapUploadMessage.value = "地图 PGM 解析或上传失败,请确认文件为 P5 格式"; @@ -769,7 +769,7 @@ async function handleMapConfigFileChange(event: Event) { rosMapMeta.configUrl = uploadedUrl; markCurrentMapUploaded({ configUrl: uploadedUrl }); - mapUploadMessage.value = "地图配置上传成功,保存下发后生效"; + mapUploadMessage.value = "地图配置上传成功,保存后生效"; scheduleMapCanvasRender(); } catch (error) { console.error(error); @@ -1507,9 +1507,26 @@ function clampMapZoom(value: number) { return Math.min(maxMapZoom, Math.max(minMapZoom, Number(value.toFixed(2)))); } -// 设置地图缩放比例并触发画布重绘 -function setMapZoom(value: number) { - mapZoom.value = clampMapZoom(value); +// 设置地图缩放比例并触发画布重绘;传入 focusPoint(画布内坐标)时缩放保持该焦点下的地图点不动 +function setMapZoom(value: number, focusPoint?: { x: number; y: number }) { + const nextZoom = clampMapZoom(value); + + if (focusPoint && nextZoom !== mapZoom.value) { + const rect = getMapStageRect(); + + if (rect && rect.width > 0 && rect.height > 0) { + const frame = getRosMapFrame(rect); + const pointerRatioX = (focusPoint.x - frame.left) / frame.width; + const pointerRatioY = (focusPoint.y - frame.top) / frame.height; + const nextWidth = frame.width * (nextZoom / mapZoom.value); + const nextHeight = frame.height * (nextZoom / mapZoom.value); + + mapPan.x += (frame.width - nextWidth) * (pointerRatioX - 0.5); + mapPan.y += (frame.height - nextHeight) * (pointerRatioY - 0.5); + } + } + + mapZoom.value = nextZoom; scheduleMapCanvasRender(); } @@ -1531,10 +1548,12 @@ function resetMapView() { focusMapOnOrigin(); } -// 处理鼠标滚轮缩放地图 +// 处理鼠标滚轮缩放地图,以光标位置为缩放中心 function handleMapWheel(event: WheelEvent) { + const rect = getMapStageRect(); const zoomFactor = event.deltaY > 0 ? 1 / 1.1 : 1.1; - setMapZoom(mapZoom.value * zoomFactor); + const focusPoint = rect ? { x: event.clientX - rect.left, y: event.clientY - rect.top } : undefined; + setMapZoom(mapZoom.value * zoomFactor, focusPoint); } // 根据地图宽高比计算默认缩放:常规比例地图保持完整显示,宽扁/高瘦地图放大让短边占满画布 @@ -2820,7 +2839,7 @@ watch( @@ -3047,7 +3066,7 @@ watch(
-
保存下发
+
保存
{{ saveProgressMessage }}