From b5f73d808241ffd9b8394a50ecc625ea455847dd Mon Sep 17 00:00:00 2001 From: "DESKTOP-I1T6TF3\\Q" <2291969160@qq.com> Date: Wed, 3 Jun 2026 07:23:28 +0800 Subject: [PATCH] fix(play): scene image renders as 1px sliver while CDN bytes still arrive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the Runware CDN download was slow (~10-20s over VPN / strict networks, vs. the optimistic <2s the existing comment assumed), the preload's 8s timeout fired and setImageUrl committed before the bytes were actually decoded. The rendered has w-auto h-auto and no intrinsic aspect-ratio source — until the image loads the layout collapses to roughly 1px tall, giving the "等了很久 → 一根线 → 突然 出图" jank. Two compounding fixes: app/play/page.tsx IMAGE_PRELOAD_TIMEOUT_MS 8000 → 20000. Real CDN+decode usually finishes well before this; pushing the ceiling out just stops the window where we commit a half-loaded URL. components/PlayCanvas.tsx Add width={1792} height={1024} HTML attrs to the scene . Doesn't affect rendered size (still driven by w-auto h-auto and the maxWidth/maxHeight in sizeStyle); the browser uses them purely as an intrinsic aspect-ratio source, so the placeholder box reserves a 16:9-ish frame even mid-download. Together: slow networks now mostly wait through preload; on the rare genuine timeout the layout still holds shape instead of collapsing. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/play/page.tsx | 12 ++++++++---- components/PlayCanvas.tsx | 10 +++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) 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. */}