添加编辑和预览
This commit is contained in:
1 parent
d46d11048f
commit
81981ad1f4
4 files changed
+79
-8
No files matched your search
+61
-7
@@ -255,10 +255,12 @@ async function getTerrainPosition(cartographic: Cartographic) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部居中:保存 -->
|
<!-- 底部居中:保存 -->
|
||||||
|
<div class="minimap-bottom-row">
|
||||||
<button class="minimap-save-btn" type="button">
|
<button class="minimap-save-btn" type="button">
|
||||||
保存
|
保存
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="minimap-zoom-slider" :class="{ 'disabled': store.lensMode === 'wide' }">
|
<div class="minimap-zoom-slider" :class="{ 'disabled': store.lensMode === 'wide' }">
|
||||||
<div class="minimap-zoom-marks">
|
<div class="minimap-zoom-marks">
|
||||||
@@ -292,7 +294,25 @@ async function getTerrainPosition(cartographic: Cartographic) {
|
|||||||
|
|
||||||
|
|
||||||
<div class="point-list-container">
|
<div class="point-list-container">
|
||||||
<div class="point-list-header">航点列表 ({{ store.pointList.length }})</div>
|
<div class="point-list-header">
|
||||||
|
<span>航点列表 ({{ store.pointList.length }})</span>
|
||||||
|
<div class="wayline-mode-toggle">
|
||||||
|
<button
|
||||||
|
:class="['wayline-mode-btn', { active: store.waylineMode === 'edit' }]"
|
||||||
|
type="button"
|
||||||
|
@click="store.setWaylineMode('edit')"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
:class="['wayline-mode-btn', { active: store.waylineMode === 'preview' }]"
|
||||||
|
type="button"
|
||||||
|
@click="store.setWaylineMode('preview')"
|
||||||
|
>
|
||||||
|
预览
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="point-list-content">
|
<div class="point-list-content">
|
||||||
<div
|
<div
|
||||||
v-for="point in store.pointList"
|
v-for="point in store.pointList"
|
||||||
@@ -477,6 +497,9 @@ async function getTerrainPosition(cartographic: Cartographic) {
|
|||||||
border-bottom: 1px solid #00D690;
|
border-bottom: 1px solid #00D690;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.point-list-content {
|
.point-list-content {
|
||||||
@@ -540,6 +563,31 @@ async function getTerrainPosition(cartographic: Cartographic) {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 航线编辑/预览模式切换(放在航点列表头部) */
|
||||||
|
.wayline-mode-toggle {
|
||||||
|
display: flex;
|
||||||
|
background: rgba(0, 0, 0, 0.35);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 2px;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wayline-mode-btn {
|
||||||
|
padding: 4px 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(255, 255, 255, 0.85);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wayline-mode-btn.active {
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
color: #2F80ED;
|
||||||
|
}
|
||||||
|
|
||||||
/* 顶部中央:镜头模式切换 */
|
/* 顶部中央:镜头模式切换 */
|
||||||
/* 左上角:放大/缩小按钮(按截图) */
|
/* 左上角:放大/缩小按钮(按截图) */
|
||||||
.minimap-expand-btn {
|
.minimap-expand-btn {
|
||||||
@@ -653,22 +701,28 @@ async function getTerrainPosition(cartographic: Cartographic) {
|
|||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 底部:保存按钮 */
|
/* 底部:编辑/预览切换 + 保存按钮 */
|
||||||
.minimap-save-btn {
|
.minimap-bottom-row {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
bottom: 18px;
|
bottom: 18px;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 160px;
|
display: flex;
|
||||||
height: 44px;
|
align-items: center;
|
||||||
|
gap: 0;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minimap-save-btn {
|
||||||
|
width: 120px;
|
||||||
|
height: 40px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #2F80ED;
|
background: #2F80ED;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 16px;
|
font-size: 15px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
pointer-events: auto;
|
|
||||||
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
|
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -14,6 +14,7 @@ export interface WayPointInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LensMode = 'wide' | 'zoom';
|
export type LensMode = 'wide' | 'zoom';
|
||||||
|
export type WaylineMode = 'edit' | 'preview';
|
||||||
|
|
||||||
export const useStore = defineStore('main', {
|
export const useStore = defineStore('main', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -21,7 +22,8 @@ export const useStore = defineStore('main', {
|
|||||||
lensMode: 'wide' as LensMode,
|
lensMode: 'wide' as LensMode,
|
||||||
pointList: [] as WayPointInfo[],
|
pointList: [] as WayPointInfo[],
|
||||||
gimbalPitch: 0, // 云台俯仰角(度)
|
gimbalPitch: 0, // 云台俯仰角(度)
|
||||||
yawAngle: 0 // 偏航角(度)
|
yawAngle: 0, // 偏航角(度)
|
||||||
|
waylineMode: 'edit' as WaylineMode
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
updateZoomFactor(zoomFactor: number) {
|
updateZoomFactor(zoomFactor: number) {
|
||||||
@@ -36,6 +38,9 @@ export const useStore = defineStore('main', {
|
|||||||
updateGimbalData(pitch: number, yaw: number) {
|
updateGimbalData(pitch: number, yaw: number) {
|
||||||
this.gimbalPitch = pitch;
|
this.gimbalPitch = pitch;
|
||||||
this.yawAngle = yaw;
|
this.yawAngle = yaw;
|
||||||
|
},
|
||||||
|
setWaylineMode(mode: WaylineMode) {
|
||||||
|
this.waylineMode = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -134,6 +134,7 @@ export class Wayline {
|
|||||||
|
|
||||||
setupDragEvent(): void {
|
setupDragEvent(): void {
|
||||||
const handler = new ScreenSpaceEventHandler(viewer.scene.canvas)
|
const handler = new ScreenSpaceEventHandler(viewer.scene.canvas)
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
let isDragging = false
|
let isDragging = false
|
||||||
let isLifting = false
|
let isLifting = false
|
||||||
@@ -142,6 +143,7 @@ export class Wayline {
|
|||||||
|
|
||||||
const scene = viewer.scene
|
const scene = viewer.scene
|
||||||
handler.setInputAction((click: ScreenSpaceEventHandler.PositionedEvent) => {
|
handler.setInputAction((click: ScreenSpaceEventHandler.PositionedEvent) => {
|
||||||
|
if (store.waylineMode === 'preview') return
|
||||||
const object = scene.pick(click.position)
|
const object = scene.pick(click.position)
|
||||||
if (object && object.id) {
|
if (object && object.id) {
|
||||||
// 检查是否点击了高度调整按钮
|
// 检查是否点击了高度调整按钮
|
||||||
@@ -160,6 +162,7 @@ export class Wayline {
|
|||||||
}, ScreenSpaceEventType.LEFT_DOWN)
|
}, ScreenSpaceEventType.LEFT_DOWN)
|
||||||
|
|
||||||
handler.setInputAction((click: ScreenSpaceEventHandler.PositionedEvent) => {
|
handler.setInputAction((click: ScreenSpaceEventHandler.PositionedEvent) => {
|
||||||
|
if (store.waylineMode === 'preview') return
|
||||||
const object = scene.pick(click.position)
|
const object = scene.pick(click.position)
|
||||||
if (object && object.id && (object.id as any).wayPoint && (object.id as any).wayPoint.selected) {
|
if (object && object.id && (object.id as any).wayPoint && (object.id as any).wayPoint.selected) {
|
||||||
isLifting = true
|
isLifting = true
|
||||||
@@ -186,6 +189,10 @@ export class Wayline {
|
|||||||
}, ScreenSpaceEventType.LEFT_UP, KeyboardEventModifier.ALT)
|
}, ScreenSpaceEventType.LEFT_UP, KeyboardEventModifier.ALT)
|
||||||
|
|
||||||
handler.setInputAction((movement: ScreenSpaceEventHandler.MotionEvent) => {
|
handler.setInputAction((movement: ScreenSpaceEventHandler.MotionEvent) => {
|
||||||
|
if (store.waylineMode === 'preview') {
|
||||||
|
scene.canvas.style.cursor = 'default'
|
||||||
|
return
|
||||||
|
}
|
||||||
const object = scene.pick(movement.endPosition)
|
const object = scene.pick(movement.endPosition)
|
||||||
if (object && object.id) {
|
if (object && object.id) {
|
||||||
if ((object.id as any).heightAdjustButton) {
|
if ((object.id as any).heightAdjustButton) {
|
||||||
@@ -231,6 +238,7 @@ export class Wayline {
|
|||||||
}, ScreenSpaceEventType.MOUSE_MOVE)
|
}, ScreenSpaceEventType.MOUSE_MOVE)
|
||||||
|
|
||||||
handler.setInputAction((movement: ScreenSpaceEventHandler.MotionEvent) => {
|
handler.setInputAction((movement: ScreenSpaceEventHandler.MotionEvent) => {
|
||||||
|
if (store.waylineMode === 'preview') return
|
||||||
if (isLifting && draggingWayPoint) {
|
if (isLifting && draggingWayPoint) {
|
||||||
const lngLat = Cartographic.fromCartesian(draggingWayPoint.position)
|
const lngLat = Cartographic.fromCartesian(draggingWayPoint.position)
|
||||||
|
|
||||||
@@ -247,6 +255,7 @@ export class Wayline {
|
|||||||
|
|
||||||
setupMovementEvent(): void {
|
setupMovementEvent(): void {
|
||||||
const { minimapViewer, uavEntity } = this
|
const { minimapViewer, uavEntity } = this
|
||||||
|
const store = useStore()
|
||||||
const camera = minimapViewer.camera
|
const camera = minimapViewer.camera
|
||||||
const keyState: KeyState = {
|
const keyState: KeyState = {
|
||||||
q: false,
|
q: false,
|
||||||
@@ -264,6 +273,7 @@ export class Wayline {
|
|||||||
|
|
||||||
window.addEventListener('keydown', (event: KeyboardEvent) => {
|
window.addEventListener('keydown', (event: KeyboardEvent) => {
|
||||||
if (event.code === 'Space') {
|
if (event.code === 'Space') {
|
||||||
|
if (store.waylineMode === 'preview') return
|
||||||
const position = minimapViewer.camera.position.clone()
|
const position = minimapViewer.camera.position.clone()
|
||||||
this.createWayPoint(position)
|
this.createWayPoint(position)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -382,8 +382,10 @@ function generateHeightAdjustButtonSvgDataUrl(): string {
|
|||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
`
|
`
|
||||||
|
|
||||||
const encoded = encodeURIComponent(svg)
|
const encoded = encodeURIComponent(svg)
|
||||||
.replace(/'/g, '%27')
|
.replace(/'/g, '%27')
|
||||||
.replace(/"/g, '%22')
|
.replace(/"/g, '%22')
|
||||||
|
|
||||||
return `data:image/svg+xml,${encoded}`
|
return `data:image/svg+xml,${encoded}`
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user