feat: 加载站点

This commit is contained in:
zhanghao 2026-08-05 14:17:16 +08:00
parent ea9314581e
commit 7c9f813246
3 changed files with 40 additions and 19 deletions

View File

@ -178,7 +178,7 @@ export const drawAdvancedAreaList = (canvasCtx, map, dataStore) => {
centroidWorldX /= vertices.length; // 求平均得到质心 X centroidWorldX /= vertices.length; // 求平均得到质心 X
centroidWorldY /= vertices.length; // 求平均得到质心 Y centroidWorldY /= vertices.length; // 求平均得到质心 Y
const centroidScreen = worldToScreen(centroidWorldX, centroidWorldY, store); const centroidScreen = worldToScreen(centroidWorldX, centroidWorldY, store);
canvasCtx.font = '500 8px "JetBrains Mono"'; // 标签字体 canvasCtx.font = '500 32px "JetBrains Mono"'; // 标签字体
canvasCtx.fillStyle = strokeColorCss; // 与描边同色 canvasCtx.fillStyle = strokeColorCss; // 与描边同色
canvasCtx.textAlign = 'center'; // 居中对齐 canvasCtx.textAlign = 'center'; // 居中对齐
canvasCtx.fillText(area.instanceName || '', centroidScreen.x, centroidScreen.y + 3); // 绘制文字 canvasCtx.fillText(area.instanceName || '', centroidScreen.x, centroidScreen.y + 3); // 绘制文字
@ -445,7 +445,7 @@ export const drawAdvancedPointList = (canvasCtx, map, dataStore) => {
} }
// ── 名称标签 ── // ── 名称标签 ──
canvasCtx.font = '500 7px "JetBrains Mono"'; canvasCtx.font = '500 12px "JetBrains Mono"';
canvasCtx.fillStyle = hexToCssRgba(pointColorHex, 0.7); canvasCtx.fillStyle = hexToCssRgba(pointColorHex, 0.7);
canvasCtx.textAlign = 'center'; canvasCtx.textAlign = 'center';
canvasCtx.fillText(advPoint.instanceName || '', pointScreen.x, pointScreen.y - diamondRadius - 4); canvasCtx.fillText(advPoint.instanceName || '', pointScreen.x, pointScreen.y - diamondRadius - 4);
@ -560,13 +560,14 @@ export const buildOccupancyGridImage = (parsedMap, showEdgeGlow) => {
} }
export class MobileRobot { export class MobileRobot {
constructor(id, name, x, y, angleRad = 0, color= "#00D4FF", imageUrl = null) { constructor(id, name, x, y, angleRad = 0, color = '#15ff00', imageUrl = null) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.x = x; // 世界坐标X (米) this.x = x; // 世界坐标X (米)
this.y = y; // 世界坐标Y (米) this.y = y; // 世界坐标Y (米)
this.angle = angleRad; // 朝向弧度 this.angle = angleRad; // 朝向弧度
this.imageUrl = imageUrl || '/bot.svg'; this.imageUrl = imageUrl || '/bot.svg';
this.color = color; // 颜色
// 预加载图片 (可选) // 预加载图片 (可选)
this.imgElement = null; this.imgElement = null;
if (this.imageUrl) { if (this.imageUrl) {
@ -596,8 +597,8 @@ export class MobileRobot {
} }
// 绘制到canvas上下文 (屏幕坐标) // 绘制到canvas上下文 (屏幕坐标)
draw(ctx, screenX, screenY, scale = 1) { draw(ctx, screenX, screenY, color, scale = 1) {
const size = 18; // 绘制大小px const size = 24; // 绘制大小px
if (this.imgElement && this.imgElement.complete) { if (this.imgElement && this.imgElement.complete) {
ctx.save(); ctx.save();
ctx.translate(screenX, screenY); ctx.translate(screenX, screenY);
@ -607,9 +608,9 @@ export class MobileRobot {
} }
// 名字标签 // 名字标签
ctx.font = '12px "JetBrains Mono"'; ctx.font = '12px "JetBrains Mono"';
ctx.fillStyle = '#a0c0f0'; ctx.fillStyle = color;
ctx.shadowBlur = 0; ctx.shadowBlur = 0;
ctx.fillText(this.name, screenX - 30, screenY - 20); ctx.fillText(this.name, screenX, screenY - 20);
} }
// 更新位置 // 更新位置

View File

@ -247,7 +247,7 @@ const drawAllRobots = (ctx) => {
if (screenPos.x + 20 < 0 || screenPos.x - 20 > inspectionStore.canvasWidthPx || screenPos.y + 20 < 0 || screenPos.y - 20 > inspectionStore.canvasHeightPx) { if (screenPos.x + 20 < 0 || screenPos.x - 20 > inspectionStore.canvasWidthPx || screenPos.y + 20 < 0 || screenPos.y - 20 > inspectionStore.canvasHeightPx) {
continue; continue;
} }
robot.draw(ctx, screenPos.x, screenPos.y); robot.draw(ctx, screenPos.x, screenPos.y, robot.color, 1);
} }
} }
@ -313,7 +313,7 @@ const updateTooltipDisplay = (hitResult) => {
if (hitResult.kind === 'robot') { if (hitResult.kind === 'robot') {
const robot = hitResult.robot; const robot = hitResult.robot;
title = `${robot.name}`; title = `${robot.name}`;
details = `<div class="tooltip-detail">位置: (${robot.x.toFixed(3)}, ${robot.y.toFixed(3)})</div> details = `<div class="tooltip-detail">位置: (${robot.x}, ${robot.y})</div>
<div class="tooltip-detail">朝向: ${(robot.angle * 180 / Math.PI).toFixed(1)}°</div> <div class="tooltip-detail">朝向: ${(robot.angle * 180 / Math.PI).toFixed(1)}°</div>
<div class="tooltip-detail">ID: ${robot.id}</div>`; <div class="tooltip-detail">ID: ${robot.id}</div>`;
} }
@ -375,8 +375,6 @@ const loadSourceMap = async () => {
const addRobot = (id, name,x, y, angleRad, color) => { const addRobot = (id, name,x, y, angleRad, color) => {
const map = applicationState.parsedMap; const map = applicationState.parsedMap;
// //
// const centerX = (map.originX + map.maxX) / 2;
// const centerY = (map.originY + map.maxY) / 2;
const robot = new MobileRobot(id, name, x, y, angleRad, color); const robot = new MobileRobot(id, name, x, y, angleRad, color);
applicationState.robots.push(robot); applicationState.robots.push(robot);
} }
@ -389,10 +387,6 @@ const moveRobot = (robot, dx, dy, dtheta = 0) => {
onMounted(() => { onMounted(() => {
init() init()
})
watch(() => props.robotList,
(newVal) => {
if (props.robotList.length > 0) { if (props.robotList.length > 0) {
loadSourceMap() loadSourceMap()
requestAnimationFrame(renderFrame); requestAnimationFrame(renderFrame);
@ -402,10 +396,35 @@ watch(() => props.robotList,
bindEvent() bindEvent()
props.robotList.forEach(item => { props.robotList.forEach(item => {
const [x, y, angle] = item.currentPosition.split(',') const [x, y, angle] = item.currentPosition.split(',')
addRobot(item.id, item.robotName, x, y, angle, '#00D4FF') addRobot(item.id, item.robotName, x, y, angle, colorList[applicationState.robots.length % colorList.length])
}) })
}, 300) }, 300)
} }
})
const colorList = ['#00D4FF', '#FFB300', '#00FF88', '#ff5100', '#fff', '#15ff00', '#ff00d4', '#00d4ff']
watch(() => props.robotList,
(newVal) => {
if (newVal.length > 0) {
const ids = applicationState.robots.map(r => r.id);
props.robotList.forEach(item => {
if (!ids.includes(item.id)) {
const [x, y, angle] = item.currentPosition.split(',')
addRobot(item.id, item.robotName, x, y, angle, colorList[applicationState.robots.length % colorList.length])
} else {
applicationState.robots.forEach(robot => {
if (robot.id === item.id) {
const [x, y, angle] = item.currentPosition.split(',')
// moveRobot(robot, parseFloat(x) - robot.x, parseFloat(y) - robot.y, parseFloat(angle) - robot.angle)
robot.x = x
robot.y = y
robot.angle = angle
}
})
}
})
}
} }
) )

View File

@ -61,7 +61,7 @@
</div> </div>
<div class="map-box"> <div class="map-box">
<MapCanvas :robotList="robotList" ref="mapCanvasRef" /> <MapCanvas v-if="robotList.length > 0" :robotList="robotList" ref="mapCanvasRef" />
</div> </div>
</div> </div>
<div class="right-container"> <div class="right-container">
@ -98,7 +98,7 @@ const robotStatus = {
} }
const getRobot = async () => { const getRobot = async () => {
let robotType let robotType
if (import.meta.env.VITE_INSPECTION_TYPE = 'inspection') { if (import.meta.env.VITE_INSPECTION_TYPE === 'inspection') {
robotType = '2' robotType = '2'
} else { } else {
robotType = '1' robotType = '1'
@ -110,6 +110,7 @@ const getRobot = async () => {
if (res.code === 200) { if (res.code === 200) {
robotList.value = res.rows robotList.value = res.rows
// getRobot()
} }
} }