fix: handle canvas context loss with recovery and fallback overlay
Listen for webglcontextlost/restored events on the fight canvas. Show "recovering" overlay on context loss, re-init scene on restore. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
bcb323e30f
commit
98e6baccc1
@@ -26,6 +26,7 @@ let scene: FightSceneController | null = null
|
||||
const sceneReady = ref(false)
|
||||
let cleanupTimerHandle: ReturnType<typeof setTimeout> | null = null
|
||||
let destroyed = false
|
||||
const contextLost = ref(false)
|
||||
|
||||
const isReplaying = ref(false)
|
||||
const ttsProgress = ref(-1)
|
||||
@@ -195,6 +196,18 @@ async function initScene() {
|
||||
container.prepend(newCanvas)
|
||||
}
|
||||
canvasRef.value = newCanvas
|
||||
contextLost.value = false
|
||||
|
||||
// Handle WebGL/Canvas context loss (GPU pressure, tab backgrounding, etc.)
|
||||
newCanvas.addEventListener('webglcontextlost', (e) => {
|
||||
e.preventDefault() // Allow context restoration
|
||||
contextLost.value = true
|
||||
sceneReady.value = false
|
||||
})
|
||||
newCanvas.addEventListener('webglcontextrestored', () => {
|
||||
contextLost.value = false
|
||||
initScene() // Re-create the scene with fresh context
|
||||
})
|
||||
|
||||
// Wrap scene creation in try/catch + timeout so a mobile sprite loading failure
|
||||
// or hang never blocks the overlay/voice/round flow
|
||||
@@ -720,6 +733,13 @@ async function _doReplay() {
|
||||
<!-- Canvas + floating overlays -->
|
||||
<div ref="canvasContainer" class="flex-1 relative min-h-0" :class="{ 'glitch-container': glitching }">
|
||||
<canvas ref="canvasRef" class="w-full h-full block" />
|
||||
<!-- Context lost fallback -->
|
||||
<div v-if="contextLost" class="absolute inset-0 z-40 bg-black/80 flex items-center justify-center">
|
||||
<div class="text-center">
|
||||
<p class="font-pixel text-xs text-ko mb-2">CANVAS CONTEXT LOST</p>
|
||||
<p class="font-mono text-[10px] text-text-muted">Recovering...</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TTS model download progress -->
|
||||
<div v-if="ttsProgress >= 0 && ttsProgress < 100" class="absolute bottom-1 left-2 right-2 z-30">
|
||||
<div class="bg-black/60 rounded px-2 py-1 flex items-center gap-2">
|
||||
|
||||
Reference in New Issue
Block a user