diff --git a/app/play/page.tsx b/app/play/page.tsx index 346ec36..90a1856 100644 --- a/app/play/page.tsx +++ b/app/play/page.tsx @@ -30,10 +30,14 @@ import type { const MUTED_STORAGE_KEY = "infiplot:muted"; // Cap how long we wait for the browser to download + decode a scene image -// before giving up and rendering anyway. Runware's CDN is normally <2s for a -// 1792×1024 PNG; tolerate up to 8s before the typewriter starts so a slow -// download can't strand the player on a blank screen forever. -const IMAGE_PRELOAD_TIMEOUT_MS = 8000; +// before giving up and rendering anyway. Runware's CDN is usually <2s for a +// 1792×1024 PNG, but over slow links / VPN / strict corp networks the same +// download can stretch to 10-20s. The previous 8s ceiling fired in that +// window, and because the rendered has no aspect-ratio occupation, the +// layout collapsed to a one-pixel-tall sliver until the bytes actually +// finished arriving — "等了很久 → 一根线 → 突然出图" of the original report. +// 20s + the aspect-video fallback together remove that failure mode. +const IMAGE_PRELOAD_TIMEOUT_MS = 20000; // ────────────────────────────────────────────────────────────────────── // Image preload — decode the Runware URL in memory before committing to diff --git a/components/PlayCanvas.tsx b/components/PlayCanvas.tsx index 023ada6..9869ff1 100644 --- a/components/PlayCanvas.tsx +++ b/components/PlayCanvas.tsx @@ -310,11 +310,19 @@ export function PlayCanvas({ className="relative inline-block" style={{ boxShadow: fullViewport ? "none" : SHADOW }} > - {/* Background image — Runware CDN URL or data URI (mock mode) */} + {/* Background image — Runware CDN URL or data URI (mock mode). + The width/height attributes are NOT rendered dimensions (w-auto + h-auto + the maxWidth/maxHeight in sizeStyle still drive the + final layout); they give the browser an intrinsic aspect ratio + so that, while the bytes are still arriving from the CDN, the + reserves a 1792:1024 box instead of collapsing to a + one-pixel sliver — fixes the "等很久 → 一根线 → 突然出图" jank. */}