优化导览页面面板与楼层交互

This commit is contained in:
lyf
2026-06-25 03:43:33 +08:00
parent 33641e75df
commit d4b97379bb
5 changed files with 252 additions and 66 deletions

View File

@@ -29,6 +29,8 @@
:target-focus-distance-factor="targetFocusDistanceFactor"
:route-preview="routePreview"
:show-route="showRoute"
:auto-switch-threshold-low="autoSwitchThresholdLow"
:auto-switch-threshold-high="autoSwitchThresholdHigh"
@floor-change="handleThreeFloorChange"
@poi-click="handlePoiClick"
@selection-clear="handleSelectionClear"
@@ -138,7 +140,12 @@
:class="`side-${floorSide}`"
:style="floorSwitcherStyle"
>
<view v-if="showFloorHeader" class="floor-header">
<view
v-if="showFloorHeader"
class="floor-header"
:class="{ active: layerMode === 'multi' }"
@tap.stop="handleFloorHeaderTap"
>
<text class="floor-header-icon"></text>
<text class="floor-header-label">楼层</text>
</view>
@@ -146,7 +153,7 @@
v-for="floor in floorLabels"
:key="floor"
class="floor-item"
:class="{ active: activeFloor === floor }"
:class="{ active: activeFloor === floor && layerMode !== 'multi' }"
@tap="handleFloorChange(floor)"
>
<text class="floor-label">{{ floor }}</text>
@@ -242,6 +249,7 @@ const props = withDefaults(defineProps<{
layerMode?: LayerDisplayMode
searchTop?: string
floorTop?: string
floorMaxHeight?: string
layerModeToggleTop?: string
toolsTop?: string
tools?: string[]
@@ -275,6 +283,8 @@ const props = withDefaults(defineProps<{
targetFocusDistanceFactor?: number
routePreview?: GuideRouteResult | null
showRoute?: boolean
autoSwitchThresholdLow?: number
autoSwitchThresholdHigh?: number
}>(), {
searchText: '请输入地点进行搜索',
activeMode: '3d',
@@ -284,6 +294,7 @@ const props = withDefaults(defineProps<{
layerMode: 'single',
searchTop: '16px',
floorTop: '164px',
floorMaxHeight: '',
layerModeToggleTop: '154px',
toolsTop: '406px',
tools: () => [] as string[],
@@ -316,7 +327,9 @@ const props = withDefaults(defineProps<{
touchGestureMode: 'orbit',
targetFocusDistanceFactor: 0.22,
routePreview: null,
showRoute: false
showRoute: false,
autoSwitchThresholdLow: 1.0,
autoSwitchThresholdHigh: 1.3
})
const emit = defineEmits<{
@@ -339,6 +352,7 @@ const indoorRendererRef = ref<{
showMultiFloor?: () => Promise<void> | void
resetCamera?: () => void
setCameraPreset?: (preset: 'top' | 'oblique') => void
zoomCamera?: (direction: 'in' | 'out') => void
clearSelection?: (shouldEmit?: boolean) => void
disableAutoSwitchTemporarily?: (durationMs: number) => void
} | null>(null)
@@ -359,7 +373,8 @@ const searchFieldStyle = computed(() => ({
}))
const floorSwitcherStyle = computed(() => ({
top: props.floorTop
top: props.floorTop,
...(props.floorMaxHeight ? { maxHeight: props.floorMaxHeight } : {})
}))
const layerModeToggleStyle = computed(() => ({
@@ -432,6 +447,10 @@ const handleLayerModeToggle = () => {
handleLayerModeChange(nextLayerMode.value)
}
const handleFloorHeaderTap = () => {
handleLayerModeChange('multi')
}
const handleToolClick = (tool: string) => {
if (props.mapType === 'indoor') {
indoorRendererRef.value?.disableAutoSwitchTemporarily?.(10000)
@@ -456,6 +475,7 @@ const handleResetView = () => {
}
const handleZoomClick = (direction: 'in' | 'out') => {
indoorRendererRef.value?.zoomCamera?.(direction)
emit('toolClick', direction === 'in' ? '放大' : '缩小')
}
@@ -797,7 +817,9 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
max-height: calc(100vh - 260px);
padding: 1px;
box-sizing: border-box;
overflow: visible;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-width: none;
background: rgba(255, 255, 255, 0.84);
border: 1px solid #dde5df;
border-radius: 8px;
@@ -805,6 +827,10 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
z-index: 35;
}
.floor-switcher::-webkit-scrollbar {
display: none;
}
.floor-switcher.side-right {
right: 16px;
}
@@ -814,6 +840,7 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
}
.floor-header {
position: relative;
min-height: 50px;
padding: 7px 4px 6px;
display: flex;
@@ -826,6 +853,10 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
border-radius: 8px 8px 0 0;
}
.floor-header.active {
background: #000000;
}
.floor-header::after {
content: '';
position: absolute;
@@ -842,12 +873,20 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
color: #151713;
}
.floor-header.active .floor-header-icon {
color: var(--museum-accent);
}
.floor-header-label {
font-size: 11px;
line-height: 14px;
color: #545861;
}
.floor-header.active .floor-header-label {
color: var(--museum-accent);
}
.layer-mode-toggle {
position: absolute;
right: 16px;