This commit is contained in:
2025-09-01 14:48:58 +08:00
parent 529886cd66
commit 35dd9b33a3
5 changed files with 2855 additions and 12639 deletions

View File

@@ -137,6 +137,7 @@ export default {
...mapGetters(['isTop'])
},
beforeDestroy () {
document.removeEventListener('keydown', this.handleKeydown);
if (this.intervalId) {
clearTimeout(this.intervalId)
}
@@ -149,9 +150,17 @@ export default {
this.$nextTick(() => {
this.initGuide()
})
document.addEventListener('keydown', this.handleKeydown);
},
methods: {
/* eslint-disable */
handleKeydown(event) {
// 仅在对话框可见时响应Enter键
if (this.dialogVisible && event.key === 'Enter') {
event.preventDefault(); // 阻止默认行为
this.stationConfirm();
}
},
initGuide() {
const config = {
// allowClose: false,

View File

@@ -33,6 +33,13 @@ export default {
allPoints: [],
pointCount: 0,
maxPoints: 1000000, // 最大点数限制
// 点云坐标范围配置(根据实际数据调整)
pointCloudRange: {
minX: 0, // 点云X轴最小值
maxX: 10, // 点云X轴最大值
minY: 0, // 点云Y轴最小值
maxY: 10 // 点云Y轴最大值
},
// 小车相关
vehicleImage: require('../../images/new/agv.png'),
carMovementEnabled: true,
@@ -43,11 +50,15 @@ export default {
previousTouchY: 0,
cameraX: 0,
cameraY: 0,
zoomRange: {
min: 0.1, // 最小缩放最多缩小到1/10原尺寸
max: 2 // 最大缩放最多放大到10倍原尺寸
},
cameraZoom: 1,
initialPinchDistance: null,
initialZoom: null,
// UI控制
pointSize: 1.5,
pointSize: 2,
// WebSocket相关
socket: null,
isLoading: true,
@@ -125,15 +136,20 @@ export default {
// 初始化Three.js场景
const container = this.$refs.canvasContainer;
const aspectRatio = container.clientWidth / container.clientHeight;
const pointRange = 1000; // 点云范围 -500 到 500
const viewHeight = pointRange;
const viewWidth = viewHeight * aspectRatio;
let viewSize = 10; // 默认初始大小
if (this.allPoints.length > 0) {
const actualRangeX = this.pointCloudRange.maxX - this.pointCloudRange.minX;
const actualRangeY = this.pointCloudRange.maxY - this.pointCloudRange.minY;
viewSize = Math.max(actualRangeX, actualRangeY) * 1.1;
}
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(
-viewWidth / 2,
viewWidth / 2,
viewHeight / 2,
-viewHeight / 2,
-viewSize * aspectRatio / 2,
viewSize * aspectRatio / 2,
viewSize / 2,
-viewSize / 2,
0.1,
2000
);
@@ -182,10 +198,10 @@ export default {
});
this.carMesh = new THREE.Sprite(carMaterial);
const container = this.$refs.canvasContainer;
const containerHeight = container.clientHeight;
const scale = this.carSize / containerHeight * 1000;
this.carMesh.scale.set(scale * 1.5, scale * 1.5, 1);
const actualRangeY = this.pointCloudRange.maxY - this.pointCloudRange.minY;
const carScale = actualRangeY / 5;
this.carMesh.scale.set(carScale * 1.5, carScale * 1.5, 1);
this.carMesh.position.set(this.carPosition.x, this.carPosition.y, 5);
this.carMesh.rotation.z = this.carPosition.angle;
this.scene.add(this.carMesh);
@@ -194,6 +210,13 @@ export default {
updatePointCloud(points) {
if (!points || !Array.isArray(points) || points.length === 0) return;
// 计算新点的范围
const newRange = this.calculateNewPointsRange(points);
// 检查是否需要扩展现有范围
const rangeExpanded = this.expandPointCloudRange(newRange);
const pointSet = new Set();
this.allPoints.forEach(point => {
const key = `${point.x},${point.y}`;
@@ -205,15 +228,93 @@ export default {
pointSet.add(key);
return true;
});
if (newUniquePoints.length === 0) return;
if (newUniquePoints.length === 0 && !rangeExpanded) return;
this.allPoints.push(...newUniquePoints);
if (this.allPoints.length > this.maxPoints) {
this.allPoints.splice(0, this.allPoints.length - this.maxPoints);
}
this.pointCount = this.allPoints.length;
this.updatePointCloudGeometry();
if (rangeExpanded) {
this.adjustCameraToNewRange();
}
},
// 计算新点的范围
calculateNewPointsRange(points) {
if (!points || points.length === 0) return null;
let minX = Infinity, maxX = -Infinity;
let minY = Infinity, maxY = -Infinity;
points.forEach(point => {
const x = point.x || 0;
const y = point.y || 0;
minX = Math.min(minX, x);
maxX = Math.max(maxX, x);
minY = Math.min(minY, y);
maxY = Math.max(maxY, y);
});
return { minX, maxX, minY, maxY };
},
// 扩展现有范围(如果新点超出了当前范围)
expandPointCloudRange(newRange) {
if (!newRange) return false;
let expanded = false;
// 初始化范围(如果是首次)
if (this.allPoints.length === 0) {
this.pointCloudRange = { ...newRange };
return true;
}
// 检查并扩展X范围
if (newRange.minX < this.pointCloudRange.minX) {
this.pointCloudRange.minX = newRange.minX;
expanded = true;
}
if (newRange.maxX > this.pointCloudRange.maxX) {
this.pointCloudRange.maxX = newRange.maxX;
expanded = true;
}
// 检查并扩展Y范围
if (newRange.minY < this.pointCloudRange.minY) {
this.pointCloudRange.minY = newRange.minY;
expanded = true;
}
if (newRange.maxY > this.pointCloudRange.maxY) {
this.pointCloudRange.maxY = newRange.maxY;
expanded = true;
}
return expanded;
},
// 新增:根据新范围调整相机
adjustCameraToNewRange() {
// 保持当前相机的缩放比例,但调整视野以适应新范围
this.updateRendererSize();
// 可选:如果希望在范围扩展时自动将新区域纳入视野
// 可以计算新的中心点并调整相机位置
const centerX = (this.pointCloudRange.minX + this.pointCloudRange.maxX) / 2;
const centerY = (this.pointCloudRange.minY + this.pointCloudRange.maxY) / 2;
// 平滑过渡到新中心(如果需要)
this.cameraX = centerX;
this.cameraY = centerY;
},
updatePointCloudGeometry() {
const positions = new Float32Array(this.pointCount * 3);
@@ -279,12 +380,18 @@ export default {
const width = container.clientWidth;
const height = container.clientHeight;
const aspectRatio = width / height;
const viewHeight = 1000;
const viewWidth = viewHeight * aspectRatio;
this.camera.left = -viewWidth / 2 / this.cameraZoom;
this.camera.right = viewWidth / 2 / this.cameraZoom;
this.camera.top = viewHeight / 2 / this.cameraZoom;
this.camera.bottom = -viewHeight / 2 / this.cameraZoom;
let viewSize = 10; // 默认大小
if (this.allPoints.length > 0) {
const actualRangeX = this.pointCloudRange.maxX - this.pointCloudRange.minX;
const actualRangeY = this.pointCloudRange.maxY - this.pointCloudRange.minY;
viewSize = Math.max(actualRangeX, actualRangeY) * 1.1; // 增加10%的边距
}
this.camera.left = -viewSize * aspectRatio / 2 / this.cameraZoom;
this.camera.right = viewSize * aspectRatio / 2 / this.cameraZoom;
this.camera.top = viewSize / 2 / this.cameraZoom;
this.camera.bottom = -viewSize / 2 / this.cameraZoom;
this.camera.updateProjectionMatrix();
this.renderer.setSize(width, height);
},
@@ -315,8 +422,8 @@ export default {
if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1) return;
// 移动相机(反转方向以获得自然拖动效果)
this.cameraX -= deltaX * 2 / this.cameraZoom;
this.cameraY += deltaY * 2 / this.cameraZoom;
this.cameraX -= deltaX * 0.3 / this.cameraZoom;
this.cameraY += deltaY * 0.3 / this.cameraZoom;
this.previousTouchX = e.touches[0].clientX;
this.previousTouchY = e.touches[0].clientY;
@@ -339,12 +446,19 @@ export default {
this.initialPinchDistance = currentDistance;
this.initialZoom = this.cameraZoom;
}
// 1. 计算新的缩放比例
let newZoom = this.initialZoom * (currentDistance / this.initialPinchDistance);
// 2. 强制限制在缩放范围内
newZoom = Math.max(this.zoomRange.min, Math.min(this.zoomRange.max, newZoom));
// 3. 更新缩放并刷新视图
if (newZoom !== this.cameraZoom) {
this.cameraZoom = newZoom;
this.updateRendererSize();
}
// 计算缩放比例
const zoomFactor = currentDistance / this.initialPinchDistance;
this.cameraZoom = Math.max(0.2, Math.min(5, this.initialZoom * zoomFactor));
this.updateRendererSize();
e.preventDefault();
}
});
@@ -369,8 +483,8 @@ export default {
if (Math.abs(deltaX) < 1 && Math.abs(deltaY) < 1) return;
this.cameraX -= deltaX * 2 / this.cameraZoom;
this.cameraY += deltaY * 2 / this.cameraZoom;
this.cameraX -= deltaX * 0.3 / this.cameraZoom;
this.cameraY += deltaY * 0.3 / this.cameraZoom;
this.previousTouchX = e.clientX;
this.previousTouchY = e.clientY;
@@ -388,11 +502,19 @@ export default {
// 鼠标滚轮缩放
canvas.addEventListener('wheel', (e)=> {
e.preventDefault();
// 优化:减小缩放步长
this.cameraZoom = e.deltaY < 0
? Math.min(5, this.cameraZoom * 1.05)
: Math.max(0.2, this.cameraZoom / 1.05);
this.updateRendererSize();
// 1. 计算新的缩放比例步长保持1.05即每次滚动缩放5%
let newZoom = e.deltaY < 0
? this.cameraZoom * 1.05 // 滚轮向上:放大
: this.cameraZoom / 1.05; // 滚轮向下:缩小
// 2. 强制限制在缩放范围内
newZoom = Math.max(this.zoomRange.min, Math.min(this.zoomRange.max, newZoom));
// 3. 更新缩放并刷新视图
if (newZoom !== this.cameraZoom) {
this.cameraZoom = newZoom;
this.updateRendererSize();
}
});
},
initWebSocket() {