From bafae0f12713da28e4f36e6917d22f9402ce5ddb Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Wed, 9 Sep 2026 16:31:02 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E6=BA=90=E7=94=BB=E5=B8=83=E9=A6=96?= =?UTF-8?q?=E5=B1=8F=E5=8A=A0=E8=BD=BD=E5=A2=9E=E5=8A=A0=E8=BD=AC=E5=9C=88?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 进入资源画布到首屏预览落地之间画布是空的,新增居中加载态:Loader2 转圈加文案,role=status 可被读屏播报 加载判定抽到 resourceBookIsLoading:有资源且布局未就绪或首屏预览一张都没落地时显示;预览失败同样视为落地,避免一直转圈 补充 resourceBookModel 加载态用例 --- apps/ai-game-creator-shell/src/styles.css | 15 ++++++ .../src/view/project-development/index.tsx | 46 +++++++++++++++++++ .../project-development/resourceBookModel.ts | 21 +++++++++ .../tests/resourceBookModel.test.ts | 28 +++++++++++ 4 files changed, 110 insertions(+) diff --git a/apps/ai-game-creator-shell/src/styles.css b/apps/ai-game-creator-shell/src/styles.css index 8017ff63c..7ea1cc2ab 100644 --- a/apps/ai-game-creator-shell/src/styles.css +++ b/apps/ai-game-creator-shell/src/styles.css @@ -5634,6 +5634,21 @@ iframe.preview-frame { pointer-events: none; } +.game-resource-book-loading { + position: absolute; + inset: 0; + z-index: 40; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + background: rgb(255 253 250 / 78%); + color: #a08073; + font-size: 13px; + pointer-events: none; +} + .game-resource-book-manager[data-book-motion='running'] .game-resource-book-scene-world { opacity: 0; diff --git a/apps/ai-game-creator-shell/src/view/project-development/index.tsx b/apps/ai-game-creator-shell/src/view/project-development/index.tsx index ed658b681..d24b0fc2b 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/index.tsx +++ b/apps/ai-game-creator-shell/src/view/project-development/index.tsx @@ -10,6 +10,7 @@ import { Image, Info, ListFilter, + Loader2, Maximize2, Minus, Music2, @@ -98,6 +99,7 @@ import { } from './resourceBookLayout'; import { initialResourceBookState, + resourceBookIsLoading, resourceBookReducer, resourceBookSceneCategory, resourceBookShowsChildCards, @@ -2189,6 +2191,36 @@ export default function ProjectDevelopmentView({ sortMode, visibleCategoryOrder, ]); + const resourceBookOverviewReady = useMemo( + () => + visibleCategoryOrder.every((category) => { + const rect = resourceBookOverviewRects.get(category); + return Boolean(rect && rect.width > 0 && rect.height > 0); + }), + [resourceBookOverviewRects, visibleCategoryOrder], + ); + const resourceBookSettledPreviewCount = useMemo(() => { + let settled = 0; + for (const resource of visibleResources) { + const identity = resourceCardPreviews.identityByResourceId.get( + resource.id, + ); + if (!identity) continue; + const status = resourceCardPreviews.previews.get(identity)?.status; + if (status === 'loaded' || status === 'failed') settled += 1; + } + return settled; + }, [ + resourceCardPreviews.identityByResourceId, + resourceCardPreviews.previews, + visibleResources, + ]); + const resourceBookLoading = resourceBookIsLoading({ + resourceCount: visibleResources.length, + overviewReady: resourceBookOverviewReady, + cardsReady: sortMode !== 'dependency' || resourceGraphInitializationReady, + settledPreviewCount: resourceBookSettledPreviewCount, + }); const setResourceCanvasViewport = useCallback( ( category: ResourceCategory, @@ -5590,6 +5622,20 @@ export default function ProjectDevelopmentView({ onWheel={handleResourceBookWheel} /> + {resourceBookLoading ? ( +
+
+ ) : null}