修复导览与讲解位置预览逻辑
This commit is contained in:
@@ -72,6 +72,7 @@ type TouchGestureMode = 'orbit' | 'pan'
|
||||
type ZoomCameraSource = 'button' | 'gesture'
|
||||
|
||||
const CANVAS_FONT_FAMILY = '"HarmonyOS Sans SC", "HarmonyOS Sans", "鸿蒙黑体", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", Arial, sans-serif'
|
||||
const FLOOR_CAMERA_DISTANCE_FACTOR = 0.78
|
||||
|
||||
interface CameraFitOptions {
|
||||
distanceFactor?: number
|
||||
@@ -203,7 +204,7 @@ const props = withDefaults(defineProps<{
|
||||
showPoi: false,
|
||||
targetFocus: null,
|
||||
touchGestureMode: 'orbit',
|
||||
targetFocusDistanceFactor: 0.22,
|
||||
targetFocusDistanceFactor: 0.36,
|
||||
routePreview: null,
|
||||
showRoute: false,
|
||||
autoSwitch: true,
|
||||
@@ -327,6 +328,9 @@ const syncControlInteractionOptions = () => {
|
||||
}
|
||||
|
||||
const corePoiCategories = new Set([
|
||||
'touring_poi',
|
||||
'exhibition_hall',
|
||||
'exhibition_hall_entrance',
|
||||
'basic_service_facility',
|
||||
'transport_circulation',
|
||||
'accessibility_special_service'
|
||||
@@ -334,10 +338,12 @@ const corePoiCategories = new Set([
|
||||
|
||||
const poiCategoryPriority: Record<string, number> = {
|
||||
target_preview: 100,
|
||||
exhibition_hall: 96,
|
||||
exhibition_hall_entrance: 92,
|
||||
touring_poi: 90,
|
||||
accessibility_special_service: 88,
|
||||
basic_service_facility: 82,
|
||||
transport_circulation: 76,
|
||||
touring_poi: 58,
|
||||
operation_experience: 46
|
||||
}
|
||||
|
||||
@@ -351,6 +357,9 @@ const poiGlyphMap: Record<string, string> = {
|
||||
stair: '梯',
|
||||
experience: '展',
|
||||
theater: '演',
|
||||
exhibition_hall: '展',
|
||||
hall_entrance: '门',
|
||||
entrance_exit: '门',
|
||||
target_preview: '位'
|
||||
}
|
||||
|
||||
@@ -2217,6 +2226,11 @@ const fitCameraToObject = (object: THREE.Object3D, preset: CameraPreset = 'obliq
|
||||
screenOffsetRatio: new THREE.Vector2(-0.045, 0.02),
|
||||
up: new THREE.Vector3(0, 1, 0)
|
||||
}
|
||||
: activeView.value === 'floor'
|
||||
? {
|
||||
distanceFactor: FLOOR_CAMERA_DISTANCE_FACTOR,
|
||||
up: new THREE.Vector3(0, 1, 0)
|
||||
}
|
||||
: {}
|
||||
|
||||
setCameraView(center, maxDim, direction, overviewFitOptions)
|
||||
@@ -2918,6 +2932,8 @@ const showFocusPoiAffordances = (poi: RenderPoi) => {
|
||||
const getPoiColor = (category: string) => {
|
||||
const colorMap: Record<string, string> = {
|
||||
touring_poi: '#2f6fed',
|
||||
exhibition_hall: '#2f6fed',
|
||||
exhibition_hall_entrance: '#4659d8',
|
||||
basic_service_facility: '#1f8f5f',
|
||||
transport_circulation: '#d77b20',
|
||||
accessibility_special_service: '#8a5cf6',
|
||||
@@ -3166,7 +3182,7 @@ const triggerPoiTapFeedback = (sprite: THREE.Sprite) => {
|
||||
getPoiSpriteUserData(sprite).feedbackUntil = performance.now() + poiTapFeedbackDurationMs
|
||||
}
|
||||
|
||||
const handleSceneTap = (event: PointerEvent) => {
|
||||
const handleSceneTap = async (event: PointerEvent) => {
|
||||
if (!camera || !renderer || !getContainerElement()) return
|
||||
|
||||
const rect = renderer.domElement.getBoundingClientRect()
|
||||
@@ -3177,7 +3193,7 @@ const handleSceneTap = (event: PointerEvent) => {
|
||||
const raycaster = new THREE.Raycaster()
|
||||
raycaster.setFromCamera(pointer, camera)
|
||||
|
||||
if (activeView.value === 'floor' && poiGroup) {
|
||||
if ((activeView.value === 'floor' || activeView.value === 'overview') && poiGroup) {
|
||||
const poiHits = raycaster.intersectObjects([...getPoiHitTargets(), ...getPoiSprites()], false)
|
||||
const hit = poiHits.find((item) => (
|
||||
item.object.visible
|
||||
@@ -3187,10 +3203,27 @@ const handleSceneTap = (event: PointerEvent) => {
|
||||
const hitMarker = hit ? getPoiMarkerFromHit(hit.object) : findNearestPoiMarkerByScreenPoint(event, rect)
|
||||
|
||||
if (hitMarker?.userData.poi) {
|
||||
const poi = hitMarker.userData.poi as RenderPoi
|
||||
const selectedPoi = hitMarker.userData.poi as RenderPoi
|
||||
if (activeView.value === 'overview') {
|
||||
disableAutoSwitchTemporarily(10000)
|
||||
try {
|
||||
await loadFloor(selectedPoi.floorId, {
|
||||
preserveCurrentSceneUntilReady: hasRenderableSceneForFloorTransition(),
|
||||
suppressProgress: true,
|
||||
allowOverviewFallback: true
|
||||
})
|
||||
emit('floorChange', selectedPoi.floorId)
|
||||
} catch (error) {
|
||||
if (isStaleModelLoadError(error)) return
|
||||
console.error('展厅点位楼层切换失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const poi = findLoadedPoi(selectedPoi.id) || selectedPoi
|
||||
const focusMarker = findPoiSprite(poi.id) || hitMarker
|
||||
selectedPOI.value = poi
|
||||
activeFocusPoiId.value = poi.id
|
||||
triggerPoiTapFeedback(hitMarker)
|
||||
triggerPoiTapFeedback(focusMarker)
|
||||
updatePoiMarkerFocus()
|
||||
showFocusPoiAffordances(poi)
|
||||
focusCameraOnPoi(poi)
|
||||
@@ -3231,7 +3264,7 @@ const handlePointerUp = (event: PointerEvent) => {
|
||||
|
||||
if (moveDistance > 8) return
|
||||
|
||||
handleSceneTap(event)
|
||||
void handleSceneTap(event)
|
||||
}
|
||||
|
||||
const emitTargetFocus = (
|
||||
@@ -3302,9 +3335,12 @@ const focusTargetPoi = async (request: TargetPoiFocusRequest) => {
|
||||
|
||||
try {
|
||||
if (activeView.value !== 'floor' || currentFloor.value !== request.floorId) {
|
||||
isLoading.value = true
|
||||
loadError.value = false
|
||||
await loadFloor(request.floorId)
|
||||
await loadFloor(request.floorId, {
|
||||
preserveCurrentSceneUntilReady: hasRenderableSceneForFloorTransition(),
|
||||
suppressProgress: true,
|
||||
allowOverviewFallback: true
|
||||
})
|
||||
isLoading.value = false
|
||||
emit('floorChange', request.floorId)
|
||||
} else if (shouldRenderPoiMarkers.value && !getPoiSprites().length) {
|
||||
@@ -3419,31 +3455,19 @@ const init3DScene = async () => {
|
||||
|
||||
const handleFloorChange = async (floorId: string) => {
|
||||
const hasSceneToKeep = hasRenderableSceneForFloorTransition()
|
||||
const showLoading = !hasSceneToKeep && !canLoadFloorSilently(floorId)
|
||||
|
||||
try {
|
||||
if (showLoading) {
|
||||
isLoading.value = true
|
||||
}
|
||||
loadError.value = false
|
||||
await loadFloor(floorId, {
|
||||
preserveCurrentSceneUntilReady: hasSceneToKeep,
|
||||
suppressProgress: !showLoading
|
||||
suppressProgress: true,
|
||||
allowOverviewFallback: true
|
||||
})
|
||||
updatePoiVisibilityByDistance()
|
||||
if (showLoading) {
|
||||
isLoading.value = false
|
||||
} else {
|
||||
isLoading.value = false
|
||||
}
|
||||
isLoading.value = false
|
||||
emit('floorChange', floorId)
|
||||
} catch (error) {
|
||||
if (isStaleModelLoadError(error)) {
|
||||
if (showLoading) {
|
||||
isLoading.value = false
|
||||
}
|
||||
return
|
||||
}
|
||||
if (isStaleModelLoadError(error)) return
|
||||
|
||||
console.error('楼层模型加载失败:', error)
|
||||
loadError.value = true
|
||||
|
||||
Reference in New Issue
Block a user