feat(frontend): cache 3D assets and restore loading feedback
Persist versioned models and validated network metadata in IndexedDB. Show scene download progress and recoverable errors with the existing frosted material. Connect existing skeletons to pending navigation and route boundaries while preserving the map. Previously only dynamic imports showed fallbacks, and rejected model promises prevented retries. Verified: 32 focused unit tests; 4 navigation and scene browser checks; 7 cache browser checks including invalid-metadata recovery; isolated production build and type checks.
This commit is contained in:
@@ -8,18 +8,36 @@
|
||||
html,body{width:100%;height:100%;margin:0;overflow:hidden;background:#e2e8e9}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif}
|
||||
canvas{display:block;width:100%;height:100%;touch-action:none}
|
||||
#boot{position:absolute;inset:0;z-index:2;display:grid;place-items:center;color:#526777;background:#e2e8e9;transition:opacity 180ms cubic-bezier(.16,1,.3,1)}
|
||||
#boot{position:absolute;inset:0;z-index:2;display:grid;place-items:center;padding:16px;box-sizing:border-box;color:#334155;background:rgba(241,245,249,.38)}
|
||||
#boot[hidden]{display:none}
|
||||
#boot span{display:flex;align-items:center;gap:10px;font-size:13px}
|
||||
#boot i{width:18px;height:18px;border:2px solid rgba(37,125,212,.22);border-top-color:#257dd4;border-radius:50%;animation:spin .8s linear infinite}
|
||||
.boot-panel{box-sizing:border-box;width:min(100%,360px);padding:24px;border-radius:16px;background:linear-gradient(135deg,rgba(255,255,255,.50),rgba(224,239,250,.28));backdrop-filter:blur(24px) saturate(170%) contrast(94%);-webkit-backdrop-filter:blur(24px) saturate(170%) contrast(94%);box-shadow:inset 0 1px 0 rgba(255,255,255,.88),inset 0 -1px 0 rgba(112,145,168,.18),0 18px 50px rgba(15,43,69,.20),0 0 0 1px rgba(255,255,255,.55)}
|
||||
.boot-heading{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:#0f172a}
|
||||
#boot i{flex:none;width:18px;height:18px;border:2px solid rgba(37,125,212,.22);border-top-color:#257dd4;border-radius:50%;animation:spin .8s linear infinite}
|
||||
#boot-detail{margin:12px 0 0;font-size:12px;line-height:1.75;overflow-wrap:anywhere}
|
||||
#boot-progress{display:block;width:100%;height:6px;margin-top:20px;accent-color:#2563eb}
|
||||
#boot-progress[hidden],#boot-retry[hidden]{display:none}
|
||||
#boot-retry{min-height:40px;margin-top:16px;padding:0 16px;border:0;border-radius:8px;background:#2563eb;color:white;font:inherit;font-size:13px;cursor:pointer;transition:transform 150ms ease,background-color 150ms ease}
|
||||
#boot-retry:hover{background:#1d4ed8}#boot-retry:active{transform:scale(.96)}#boot-retry:focus-visible{outline:2px solid #2563eb;outline-offset:3px}
|
||||
#boot[data-state=error] i{animation:none;border-color:#dc2626;background:#fee2e2}
|
||||
#boot[data-state=error] #boot-title{color:#991b1b}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
@media(prefers-reduced-motion:reduce){#boot i{animation:none;border-top-color:rgba(37,125,212,.22)}}
|
||||
@media(prefers-reduced-motion:reduce){#boot i{animation:none;border-top-color:rgba(37,125,212,.22)}#boot-retry{transition:none}}
|
||||
</style>
|
||||
<script type="importmap">{"imports":{"three":"./vendor/three/three.module.js","three/addons/":"./vendor/three/addons/"}}</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="boot" role="status"><span><i aria-hidden="true"></i>正在载入三维模型</span></div>
|
||||
<div id="boot" role="status" aria-live="polite" aria-busy="true" data-state="loading">
|
||||
<div class="boot-panel">
|
||||
<div class="boot-heading"><i aria-hidden="true"></i><span id="boot-title">正在准备三维场景</span></div>
|
||||
<p id="boot-detail">首次载入需要下载模型,后续将优先使用本地缓存。</p>
|
||||
<progress id="boot-progress" aria-label="场景资源加载进度"></progress>
|
||||
<button id="boot-retry" type="button" hidden>重新载入场景</button>
|
||||
</div>
|
||||
</div>
|
||||
<output id="qa" hidden></output>
|
||||
<script type="module" src="./preview.mjs?v=34-detailed-network-context"></script>
|
||||
<script type="module">
|
||||
import {failLoading} from './loadingProgress.mjs?v=35-resource-cache';
|
||||
import('./preview.mjs?v=35-resource-cache').catch(failLoading);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user