feat(map): 优化地图缩放逻辑及点位渲染

- 将设备管理地图最大缩放比例提升至15,支持更大范围缩放
- 修改地图缩放增量为按倍率缩放,提升缩放体验平滑度
- 新增根据地图宽高比计算默认缩放,消除宽扁地图显示过小问题
- 自动缩放时聚焦地图原点,提升用户定位便利性
- 调整地图点位渲染样式,统一圆圈大小,简化视觉效果,只用描边色区分
- 移除点位标签背景框绘制,减少视觉干扰
- 鼠标滚轮缩放时以光标为中心,缩放过程视野自动平移保持焦点
- 集成中心页面地图缩放支持按倍率调整和平滑过渡
- 优化保存巡检任务时进度条逻辑,取消模拟递增,调用完成立即完成进度
- 增强地图缩放动画过渡时长,从0.18秒提升至0.45秒
- 修复集成中心页面真实点位显示优化,起点终点显示标签,途经点隐藏标签
This commit is contained in:
2026-08-12 11:11:07 +08:00
parent d29075e9b4
commit 03d319ebf6
2 changed files with 106 additions and 122 deletions

View File

@@ -668,7 +668,7 @@ const realRoutePath = computed(() => routeMapPoints.value
.join(" "));
const realCheckPoints = computed(() => routeMapPoints.value.map((point, index) => ({
...point,
label: index === 0 ? "起点" : index === routeMapPoints.value.length - 1 ? "终点" : "途经点",
label: index === 0 ? "起点" : index === routeMapPoints.value.length - 1 ? "终点" : "",
})));
const inspectionRunning = computed(() => currentInspection.value?.status === 0);
const inspectionStatusText = computed(() => inspectionRunning.value ? "巡检中" : "空闲");
@@ -1270,9 +1270,10 @@ function switchDriveMode(mode: DriveMode) {
activeDriveMode.value = mode;
}
// 调整真实 ROS 地图整体缩放,不影响底部状态浮层
// 调整真实 ROS 地图整体缩放,不影响底部状态浮层,倍率越高放大步进越大
function changeMapScale(delta: number) {
mapScale.value = Math.min(3, Math.max(0.55, Number((mapScale.value + delta).toFixed(2))));
const factor = delta > 0 ? 1.1 : 1 / 1.1;
mapScale.value = Math.min(15, Math.max(0.55, Number((mapScale.value * factor).toFixed(2))));
}
function resetMapScale() {
@@ -1280,10 +1281,34 @@ function resetMapScale() {
mapOffset.value = { x: 0, y: 0 };
}
// 鼠标滚轮缩放地图内容,按住拖拽平移地图视野
// 鼠标滚轮以光标为缩放中心缩放地图内容,按住拖拽平移地图视野
function handleMapWheel(event: WheelEvent) {
event.preventDefault();
changeMapScale(event.deltaY > 0 ? -0.05 : 0.05);
if (!rosMap.value || !navMapSvgRef.value) {
return;
}
const factor = event.deltaY > 0 ? 1 / 1.1 : 1.1;
const nextScale = Math.min(15, Math.max(0.55, Number((mapScale.value * factor).toFixed(2))));
if (nextScale === mapScale.value) {
return;
}
// 缩放前后保持光标下的地图点位置不动,需要同步平移视野
const rect = navMapSvgRef.value.getBoundingClientRect();
const pointerX = (event.clientX - rect.left) * (rosMap.value.width / rect.width);
const pointerY = (event.clientY - rect.top) * (rosMap.value.height / rect.height);
const centerX = rosMap.value.width / 2;
const centerY = rosMap.value.height / 2;
const keepRatio = 1 - nextScale / mapScale.value;
mapOffset.value = {
x: mapOffset.value.x + (pointerX - centerX) * keepRatio,
y: mapOffset.value.y + (pointerY - centerY) * keepRatio,
};
mapScale.value = nextScale;
}
function startMapDrag(event: PointerEvent) {
@@ -1539,10 +1564,10 @@ function getStatusClass(status: DeviceItem["status"]) {
<path v-if="realRoutePath" class="route-glow" :d="realRoutePath" />
<path v-if="realRoutePath" class="route-line" :d="realRoutePath" />
<g class="checkpoint-layer">
<g v-for="point in realCheckPoints" :key="`${point.label}-${point.x}-${point.y}`" class="checkpoint"
<g v-for="(point, index) in realCheckPoints" :key="index" class="checkpoint"
:transform="`translate(${point.x}, ${point.y})`">
<circle r="3"></circle>
<text x="7" y="2.5">{{ point.label }}</text>
<text v-if="point.label" x="7" y="2.5">{{ point.label }}</text>
</g>
</g>
<g v-if="robotMapPoint" class="robot-layer real-robot-layer"