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:
Dorian
2026-03-09 09:18:33 +00:00
co-authored by Claude Opus 4.6
parent bcb323e30f
commit 98e6baccc1
+20
View File
@@ -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">