diff --git a/frontend/src/components/FightViewer.vue b/frontend/src/components/FightViewer.vue index a8377c1..6dbf639 100644 --- a/frontend/src/components/FightViewer.vue +++ b/frontend/src/components/FightViewer.vue @@ -112,12 +112,17 @@ async function initScene() { const container = canvasContainer.value if (!container) return + // Wait for container to have dimensions (layout may not be complete yet) + for (let i = 0; i < 10 && (!container.clientWidth || !container.clientHeight); i++) { + await new Promise(r => requestAnimationFrame(r)) + } + // Replace canvas element so Kaplay gets a fresh context const oldCanvas = canvasRef.value const newCanvas = document.createElement('canvas') newCanvas.className = 'w-full h-full block' - newCanvas.width = container.clientWidth - newCanvas.height = container.clientHeight + newCanvas.width = container.clientWidth || 800 + newCanvas.height = container.clientHeight || 500 if (oldCanvas) { oldCanvas.replaceWith(newCanvas) } else { diff --git a/frontend/src/pages/FightPage.vue b/frontend/src/pages/FightPage.vue index 266c605..81b3cdd 100644 --- a/frontend/src/pages/FightPage.vue +++ b/frontend/src/pages/FightPage.vue @@ -305,21 +305,30 @@ async function initLiveScene() { const container = liveCanvas.value.parentElement if (container) { + // Wait for container to have dimensions + for (let i = 0; i < 10 && (!container.clientWidth || !container.clientHeight); i++) { + await new Promise(r => requestAnimationFrame(r)) + } const oldCanvas = liveCanvas.value const newCanvas = document.createElement('canvas') newCanvas.className = oldCanvas.className - newCanvas.width = container.clientWidth - newCanvas.height = container.clientHeight + newCanvas.width = container.clientWidth || 800 + newCanvas.height = container.clientHeight || 500 oldCanvas.replaceWith(newCanvas) liveCanvas.value = newCanvas } - liveScene = await createFightScene({ - canvas: liveCanvas.value, - botA: { name: data.botA.name, seed: data.botA.avatarSeed || data.botA.name, tier: data.botA.tier, archetype: data.botA.archetype, customization: data.botA.customization, wins: data.botA.wins, losses: data.botA.losses }, - botB: { name: data.botB.name, seed: data.botB.avatarSeed || data.botB.name, tier: data.botB.tier, archetype: data.botB.archetype, customization: data.botB.customization, wins: data.botB.wins, losses: data.botB.losses }, - arena: data.arena, - }) + try { + liveScene = await createFightScene({ + canvas: liveCanvas.value, + botA: { name: data.botA.name, seed: data.botA.avatarSeed || data.botA.name, tier: data.botA.tier, archetype: data.botA.archetype, customization: data.botA.customization, wins: data.botA.wins, losses: data.botA.losses }, + botB: { name: data.botB.name, seed: data.botB.avatarSeed || data.botB.name, tier: data.botB.tier, archetype: data.botB.archetype, customization: data.botB.customization, wins: data.botB.wins, losses: data.botB.losses }, + arena: data.arena, + }) + } catch (err) { + console.error('[FightPage] createFightScene failed:', err) + liveScene = null + } liveSceneReady.value = true