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. */}
