同步加载页与首页模型加载状态

This commit is contained in:
lyf
2026-07-06 10:11:20 +08:00
parent b99ae572da
commit 4a6a7f9c29
3 changed files with 151 additions and 14 deletions

View File

@@ -75,6 +75,14 @@ type CameraPreset = 'top' | 'oblique'
type TouchGestureMode = 'orbit' | 'pan'
type ZoomCameraSource = 'button' | 'gesture'
interface InitialModelProgressEvent {
progress: number
message: string
view: ViewMode
floorId?: string
elapsedMs?: number
}
const CANVAS_FONT_FAMILY = '"鸿蒙黑体", "HarmonyOS Sans SC", "HarmonyOS Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
const FLOOR_CAMERA_DISTANCE_FACTOR = 0.78
const SGS_VISUAL_RENDER_CONFIG = {
@@ -300,6 +308,7 @@ const emit = defineEmits<{
targetFocus: [result: TargetPoiFocusResult]
autoSwitch: [event: { from: 'overview' | 'floor'; to: 'overview' | 'floor'; trigger: 'zoom-in' | 'zoom-out'; distance: number }]
autoSwitchBlocked: [reason: { reason: 'loading-locked' | 'cooldown' | 'disabled' }]
initialModelProgress: [event: InitialModelProgressEvent]
initialModelReady: [event: { view: ViewMode; floorId?: string; elapsedMs?: number }]
initialModelFailed: [event: { view: ViewMode; floorId?: string; message: string; elapsedMs?: number }]
}>()
@@ -385,6 +394,7 @@ let cameraTween: CameraTweenState | null = null
let adjacentPreloadSeq = 0
let firstModelLoadStartedAt = 0
let firstModelVisibleReported = false
let initialModelSettled = false
const cameraTweenEnabled = true
const cameraTweenDurationMs = 480
@@ -1442,8 +1452,19 @@ const handleControlEnd = () => {
}
const setProgress = (progress: number, message: string) => {
loadingProgress.value = Math.min(100, Math.max(0, progress))
const normalizedProgress = Math.min(100, Math.max(0, progress))
loadingProgress.value = normalizedProgress
loadingMessage.value = message
if (firstModelLoadStartedAt && !initialModelSettled) {
emit('initialModelProgress', {
progress: normalizedProgress,
message,
view: activeView.value,
floorId: currentFloor.value,
elapsedMs: Math.round(getNow() - firstModelLoadStartedAt)
})
}
}
const markFirstModelVisible = (
@@ -4713,6 +4734,7 @@ const init3DScene = async () => {
isDisposed = false
firstModelLoadStartedAt = getNow()
firstModelVisibleReported = false
initialModelSettled = false
isLoading.value = true
loadError.value = false
selectedPOI.value = null
@@ -4727,6 +4749,7 @@ const init3DScene = async () => {
await loadModelPackage()
setProgress(100, '馆内三维模型加载完成')
initialModelSettled = true
isLoading.value = false
emit('initialModelReady', {
view: activeView.value,
@@ -4743,6 +4766,7 @@ const init3DScene = async () => {
isLoading.value = false
const message = error instanceof Error ? error.message : '请检查模型资源或网络状态后重试'
setProgress(0, message)
initialModelSettled = true
emit('initialModelFailed', {
view: activeView.value,
floorId: currentFloor.value,

View File

@@ -26,6 +26,7 @@
@selection-clear="handleSelectionClear"
@target-focus="handleTargetFocus"
@auto-switch="handleAutoSwitch"
@initial-model-progress="handleInitialModelProgress"
@initial-model-ready="handleInitialModelReady"
@initial-model-failed="handleInitialModelFailed"
/>
@@ -289,6 +290,14 @@ type IndoorViewMode = 'overview' | 'floor' | 'multi'
type LayerDisplayMode = 'single' | 'multi'
type TouchGestureMode = 'orbit' | 'pan'
interface InitialModelProgressEvent {
progress: number
message: string
view: IndoorViewMode
floorId?: string
elapsedMs?: number
}
const props = withDefaults(defineProps<{
searchText?: string
activeMode?: '2d' | '3d'
@@ -403,6 +412,7 @@ const emit = defineEmits<{
selectionClear: []
targetFocus: [result: TargetPoiFocusResult]
autoSwitch: [event: { from: 'overview' | 'floor'; to: 'overview' | 'floor'; trigger: string; distance: number }]
initialModelProgress: [event: InitialModelProgressEvent]
initialModelReady: [event: { view: IndoorViewMode; floorId?: string; elapsedMs?: number }]
initialModelFailed: [event: { view: IndoorViewMode; floorId?: string; message: string; elapsedMs?: number }]
mapTap: [location: { latitude: number; longitude: number }]
@@ -710,6 +720,10 @@ const handleAutoSwitch = (event: { from: 'overview' | 'floor'; to: 'overview' |
emit('autoSwitch', event)
}
const handleInitialModelProgress = (event: InitialModelProgressEvent) => {
emit('initialModelProgress', event)
}
const handleInitialModelReady = (event: { view: IndoorViewMode; floorId?: string; elapsedMs?: number }) => {
emit('initialModelReady', event)
}