生成提示词
{referenceEnabled ? (
/*
@@ -433,7 +433,7 @@ export function ResourceCanvasAssetGenerationPanelView({
versions={versions}
activeVersionId={activeVersionId}
multiline
- rows={6}
+ rows={3}
placeholder={`${action.promptPlaceholder}(可用 @ 选择参考图)`}
showPolishAction={false}
/>
@@ -442,7 +442,7 @@ export function ResourceCanvasAssetGenerationPanelView({
)}
-
- {referenceEnabled && referenceLimit > 0 ? (
-
- {`参考图 ${referenceAssetIds.length}/${referenceLimit}`}
-
- ) : null}
{referenceProblemNotice ? (
) : null}
+ {/*
+ 动作行收口:润色入口、参考图计数与两个按钮挤在同一行。
+
+ 原先「润色一行、参考图计数一行、按钮一行」把面板顶到必须滚动(验收现场截图里那条
+ 滚动条),而这三块内容都没有独占一行的必要:润色作用在提示词上、计数是提示词的从属
+ 信息、按钮是收尾动作。放一行之后面板高度回落到几何上界以内,滚动条物理上不再出现。
+ */}
-
- 取消
-
-
-
- {action.label}
-
+
+ {referenceEnabled && referenceLimit > 0 ? (
+
+ {`参考图 ${referenceAssetIds.length}/${referenceLimit}`}
+
+ ) : null}
+
+
+ 取消
+
+
+
+ {action.label}
+
+
>
diff --git a/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasGenerationPanel.css b/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasGenerationPanel.css
index 7d19a99ec..9983b191c 100644
--- a/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasGenerationPanel.css
+++ b/apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasGenerationPanel.css
@@ -14,8 +14,9 @@
align-content: center;
gap: 4px;
padding: 8px;
+ /* 差异只留「虚线 + 更深的描边」(表示还没落地);圆角与浮层卡共用基类 token。 */
border: 1px dashed #c9a493;
- border-radius: 14px;
+ border-radius: var(--game-canvas-card-radius-inner, 14px);
background: rgb(255 250 247 / 88%);
color: #8a6a5c;
text-align: center;
@@ -80,14 +81,70 @@
/* 锚点给的是占位卡中心:不居中就会整体右偏半个面板宽(真实浏览器 x287 vs 卡中心 286 复现过)。 */
transform: translateX(-50%);
width: min(560px, calc(100% - 24px));
+ /* 外形走基类 token(= 网页端画布面板那一套),三块浮层因此长得一样。 */
+ border: 1px solid var(--game-canvas-card-border, #e4c8ba);
+ border-radius: var(--game-canvas-card-radius, 18px);
+ background: var(--game-canvas-card-fill, #fffaf7);
+ box-shadow: var(--game-canvas-card-shadow, 0 24px 64px rgb(62 37 27 / 24%));
+ padding: var(--game-canvas-card-padding, 18px);
overflow-y: auto;
overflow-x: hidden;
overscroll-behavior: contain;
pointer-events: auto;
- /* 内联 `maxHeight` 按真实画布底边算;这条只是拿不到几何时的兜底上界。 */
+ /*
+ * 内联 `maxHeight` 按真实画布底边算;这条只是拿不到几何时的兜底上界。
+ *
+ * 面板内容已经压到「一行提示词 + 一行参数 + 一行动作」的紧凑版(见下面那组规则),正常几何下
+ * 根本到不了这里;`overflow` 与这条上界保留为极端窗口下的兜底,而不是日常出现的滚动条。
+ */
max-height: min(560px, calc(100dvh - 160px));
}
+/*
+ * 紧凑版:字段行两列(标签在左、控件在右)、比例与尺寸并排、动作用一行收口。
+ *
+ * 验收现场那张图里面板要滚动,是因为「标签各占一行 + 提示词 6 行 + 比例一行 + 尺寸一行 + 润色
+ * 一行 + 参考计数一行」把内容顶到几何上界之外。这里按信息层级重新排:从属信息(标签、计数、
+ * 润色)让位给主体(提示词、参数、动作),面板高度回落到上界以内,滚动条物理上不再出现。
+ */
+.game-resource-generation-form {
+ gap: 10px;
+}
+
+.game-resource-generation-form > label,
+.game-resource-generation-form
+ > .resource-canvas-asset-generation-prompt-field {
+ display: grid;
+ grid-template-columns: auto minmax(0, 1fr);
+ align-items: center;
+ gap: 4px 10px;
+}
+
+.resource-canvas-asset-generation-prompt-field > span,
+.game-resource-generation-form > label > span {
+ white-space: nowrap;
+}
+
+/* 比例(5 项)与尺寸(3 项)并排:两组都很短,各占半行足够点。 */
+.resource-canvas-asset-generation-dimensions {
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
+ gap: 8px;
+}
+
+/* 动作行:润色与参考计数贴左,两个按钮贴右,同一行收口。 */
+.game-approval-dialog.resource-canvas-generation-floating-panel
+ .game-resource-generation-actions {
+ align-items: center;
+ gap: 10px;
+ padding-top: 2px;
+}
+
+.game-resource-generation-actions-buttons {
+ display: flex;
+ margin-left: auto;
+ gap: 8px;
+}
+
/*
* 提交行固定在浮层底部。
*
@@ -113,4 +170,5 @@
margin: 0;
color: #9a7d70;
font-size: 11px;
+ white-space: nowrap;
}
diff --git a/apps/ai-game-creator-shell/src/styles.css b/apps/ai-game-creator-shell/src/styles.css
index ae3c7bd86..6833fd921 100644
--- a/apps/ai-game-creator-shell/src/styles.css
+++ b/apps/ai-game-creator-shell/src/styles.css
@@ -9546,6 +9546,26 @@ iframe.preview-frame {
box-shadow: 0 24px 64px rgb(62 37 27 / 24%);
}
+/*
+ * 画布卡片基类 token。
+ *
+ * 取值**照抄网页端美术画布的面板**(`src/index.css` 的 `.image-canvas-editor__generation-composer`
+ * 一族):占位卡、生成浮层 / 弹窗、资源信息浮层从此共用同一组圆角 / 描边 / 底色 / 投影,各卡
+ * 自己的规则只表达差异(占位卡虚线描边、浮层的定位与宽度、信息浮层的窄宽…)。
+ *
+ * 两块从网页端整站表逐条照抄下来的浮层(快速编辑 / 生成动画)本身不在这里改——它们的取值由
+ * `tests/resourceCanvasCharacterAnimationPanelStyle.test.tsx` 逐条比对,改了会直接把守卫打红;
+ * 它们本来就是这套取值的来源。
+ */
+.game-project-workbench {
+ --game-canvas-card-radius: 1.1rem;
+ --game-canvas-card-radius-inner: 0.85rem;
+ --game-canvas-card-border: rgba(148, 163, 184, 0.36);
+ --game-canvas-card-fill: rgba(255, 255, 255, 0.96);
+ --game-canvas-card-shadow: 0 22px 48px rgba(15, 23, 42, 0.22);
+ --game-canvas-card-padding: 0.76rem;
+}
+
.game-approval-dialog > header {
display: flex;
align-items: flex-start;
diff --git a/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationReferences.test.tsx b/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationReferences.test.tsx
index be6c4c2ba..a8001ff90 100644
--- a/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationReferences.test.tsx
+++ b/apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationReferences.test.tsx
@@ -330,6 +330,64 @@ describe('生成面板的参考接线', () => {
).not.toBeNull();
});
+ test('紧凑版排布:动作行同时装下润色 / 参考计数 / 两个动作,参数与提示词各占一行', () => {
+ const imageAsset = asset('asset-a', 'image/png', 'assets/素材-a.png');
+ render(
+ undefined}
+ />,
+ );
+
+ const panel = screen.getByRole('dialog', { name: '生成图片' });
+ /*
+ 验收现场那张图里面板要滚动:标签各占一行、提示词 6 行、比例与尺寸各占一行、润色与参考
+ 计数又各占一行。这里钉住重排后的形状——动作行一行收口、参数两栏并排、提示词三行,
+ 面板高度因此回落到几何上界以内(滚动条不该再出现)。
+ */
+ const actions = panel.querySelector('.game-resource-generation-actions');
+ expect(actions).not.toBeNull();
+ expect(
+ within(actions as HTMLElement).getByRole('button', { name: 'AI 润色' }),
+ ).not.toBeNull();
+ expect(
+ within(actions as HTMLElement).getByText('参考图 0/5'),
+ ).not.toBeNull();
+ expect(
+ within(actions as HTMLElement).getByRole('button', { name: '取消' }),
+ ).not.toBeNull();
+ expect(
+ within(actions as HTMLElement).getByRole('button', { name: '生成图片' }),
+ ).not.toBeNull();
+
+ // 比例与尺寸同处一格(CSS 里排成两栏),不再各占一行。
+ const dimensions = panel.querySelectorAll(
+ '.resource-canvas-asset-generation-dimensions',
+ );
+ expect(dimensions).toHaveLength(1);
+ // 两组选择器(比例 5 项、尺寸 3 项)同处这一格,CSS 里排成两栏。
+ expect(
+ within(dimensions[0] as HTMLElement).getByRole('button', {
+ name: '生成图片比例 1:1',
+ }),
+ ).not.toBeNull();
+ expect(
+ within(dimensions[0] as HTMLElement).getByRole('button', {
+ name: '生成图片尺寸 1K',
+ }),
+ ).not.toBeNull();
+ });
+
test('超限时提交被挡住并给出原因', async () => {
const user = userEvent.setup();
const onSubmit =