From 4a12b090b54db9b45ba3bbd3ce3eef5ef5266fca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BA=94=E9=A6=99=E4=B8=B8=E5=AD=90?= <15518898337@163.com>
Date: Wed, 24 Jun 2026 16:19:01 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=90=84=E5=85=83=E7=B4=A0?=
=?UTF-8?q?=E8=BE=93=E5=85=A5=E6=A1=86=E4=B8=AD=E7=9A=84=E5=90=AF=E5=8F=91?=
=?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=96=87=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
音效、背景音乐和图标素材改为空值加灰色启发提示。
角色规范、图标规范和自定义规范输入框补充灰色启发提示。
同步更新相关前端组件测试。
---
.../ImageCanvasGenerationComposerView.tsx | 4 +-
.../ImageCanvasGenerationDialogModel.test.ts | 39 +++++++++++------
.../ImageCanvasGenerationDialogModel.ts | 24 ++++++-----
...CanvasIconSpritesheetComposerView.test.tsx | 12 ++++++
...ImageCanvasIconSpritesheetComposerView.tsx | 5 +--
...mageCanvasSpecGenerationPanelView.test.tsx | 42 +++++++++++++++++++
.../ImageCanvasSpecGenerationPanelView.tsx | 16 +++++++
src/index.css | 8 ++++
8 files changed, 122 insertions(+), 28 deletions(-)
diff --git a/src/components/image-editor/ImageCanvasGenerationComposerView.tsx b/src/components/image-editor/ImageCanvasGenerationComposerView.tsx
index d7573c6ed..c0753550c 100644
--- a/src/components/image-editor/ImageCanvasGenerationComposerView.tsx
+++ b/src/components/image-editor/ImageCanvasGenerationComposerView.tsx
@@ -779,8 +779,8 @@ function ImageCanvasAudioGenerationComposerView({
disabled={isGenerating}
placeholder={
isSoundEffect
- ? '描述需要生成的游戏音效'
- : '描述需要生成的游戏背景音乐'
+ ? '你希望生成什么音效?'
+ : '你希望生成什么音乐?'
}
size="sm"
density="compact"
diff --git a/src/components/image-editor/ImageCanvasGenerationDialogModel.test.ts b/src/components/image-editor/ImageCanvasGenerationDialogModel.test.ts
index e40487f25..6eb956973 100644
--- a/src/components/image-editor/ImageCanvasGenerationDialogModel.test.ts
+++ b/src/components/image-editor/ImageCanvasGenerationDialogModel.test.ts
@@ -74,6 +74,28 @@ describe('ImageCanvasGenerationDialogModel', () => {
originalHeight: 1024,
},
});
+ expect(
+ createSpecDialogDraft({ canvasSize, viewport, specType: 'character' }),
+ ).toMatchObject({
+ mode: 'spec',
+ specType: 'character',
+ specValues: {
+ playSetting: '',
+ artStyle: '',
+ bodyRatio: '3',
+ },
+ });
+ expect(
+ createSpecDialogDraft({ canvasSize, viewport, specType: 'ui' }),
+ ).toMatchObject({
+ mode: 'spec',
+ specType: 'ui',
+ specValues: {
+ playSetting: '',
+ artStyle: '',
+ bodyRatio: '3',
+ },
+ });
expect(
createSpecDialogDraft({ canvasSize, viewport, specType: 'icon' }),
).toMatchObject({
@@ -153,16 +175,9 @@ describe('ImageCanvasGenerationDialogModel', () => {
imageModel: 'unknown-model',
aspectRatio: '1:1',
imageSize: '1K',
- prompt: '返回按钮\n设置按钮\n下一关按钮\n提示按钮\n原图按钮\n冻结按钮',
+ prompt: '',
iconSpecReference: null,
- iconDescriptions: [
- '返回按钮',
- '设置按钮',
- '下一关按钮',
- '提示按钮',
- '原图按钮',
- '冻结按钮',
- ],
+ iconDescriptions: [],
placeholder: {
x: 300,
y: 180,
@@ -228,8 +243,7 @@ describe('ImageCanvasGenerationDialogModel', () => {
expect(createSoundEffectGenerationDialogDraft({ canvasSize, viewport }))
.toMatchObject({
mode: 'audio-sound-effect',
- prompt:
- '短促清脆的游戏交互音效,带轻微闪光质感,干净收尾,适合按钮确认或收集奖励。',
+ prompt: '',
status: 'idle',
composerOpen: true,
soundModel: 'audio1.0',
@@ -246,8 +260,7 @@ describe('ImageCanvasGenerationDialogModel', () => {
expect(createBackgroundMusicGenerationDialogDraft({ canvasSize, viewport }))
.toMatchObject({
mode: 'audio-background-music',
- prompt:
- '适合轻松冒险游戏的循环背景音乐,温暖明亮,旋律简洁,不包含人声。',
+ prompt: '',
status: 'idle',
composerOpen: true,
makeInstrumental: true,
diff --git a/src/components/image-editor/ImageCanvasGenerationDialogModel.ts b/src/components/image-editor/ImageCanvasGenerationDialogModel.ts
index c54fc5dd5..e08aad069 100644
--- a/src/components/image-editor/ImageCanvasGenerationDialogModel.ts
+++ b/src/components/image-editor/ImageCanvasGenerationDialogModel.ts
@@ -50,11 +50,6 @@ const VIDEO_REFERENCE_LIMITS = {
video: 3,
audio: 3,
} as const;
-const DEFAULT_SOUND_EFFECT_PROMPT =
- '短促清脆的游戏交互音效,带轻微闪光质感,干净收尾,适合按钮确认或收集奖励。';
-const DEFAULT_BACKGROUND_MUSIC_PROMPT =
- '适合轻松冒险游戏的循环背景音乐,温暖明亮,旋律简洁,不包含人声。';
-
function getViewportWorldCenter({
canvasSize,
viewport,
@@ -194,6 +189,10 @@ export function createGenerateDialogDraft({
};
}
+function shouldUseSpecPlaceholderValues(specType: SpecGenerationType) {
+ return specType === 'character' || specType === 'ui';
+}
+
export function createSpecDialogDraft({
canvasSize,
viewport,
@@ -210,7 +209,12 @@ export function createSpecDialogDraft({
status: 'idle',
composerOpen: true,
specType,
- specValues: { ...DEFAULT_SPEC_FORM_VALUES[specType] },
+ specValues: {
+ ...DEFAULT_SPEC_FORM_VALUES[specType],
+ ...(shouldUseSpecPlaceholderValues(specType)
+ ? { playSetting: '', artStyle: '' }
+ : {}),
+ },
placeholder: {
x: worldCenter.x - SPEC_FRAME_ORIGINAL_SIZE.width / 2,
y: worldCenter.y - SPEC_FRAME_ORIGINAL_SIZE.height / 2,
@@ -274,11 +278,11 @@ export function createIconGenerationDialogDraft({
const dimensionDefaults = resolveImageDimensionDefaults(normalizedImageModel);
return {
mode: 'icon',
- prompt: formatIconDescriptionsText(DEFAULT_ICON_DESCRIPTIONS),
+ prompt: '',
status: 'idle',
composerOpen: true,
iconSpecReference: null,
- iconDescriptions: [...DEFAULT_ICON_DESCRIPTIONS],
+ iconDescriptions: [],
imageModel: normalizedImageModel,
aspectRatio: dimensionDefaults.aspectRatio,
imageSize: dimensionDefaults.imageSize,
@@ -373,7 +377,7 @@ export function createSoundEffectGenerationDialogDraft({
const worldCenter = getViewportWorldCenter({ canvasSize, viewport });
return {
mode: 'audio-sound-effect',
- prompt: DEFAULT_SOUND_EFFECT_PROMPT,
+ prompt: '',
status: 'idle',
composerOpen: true,
soundModel: DEFAULT_SOUND_EFFECT_MODEL,
@@ -399,7 +403,7 @@ export function createBackgroundMusicGenerationDialogDraft({
const worldCenter = getViewportWorldCenter({ canvasSize, viewport });
return {
mode: 'audio-background-music',
- prompt: DEFAULT_BACKGROUND_MUSIC_PROMPT,
+ prompt: '',
status: 'idle',
composerOpen: true,
makeInstrumental: true,
diff --git a/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.test.tsx b/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.test.tsx
index df6449cf4..2bafdbee3 100644
--- a/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.test.tsx
+++ b/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.test.tsx
@@ -103,6 +103,18 @@ describe('ImageCanvasIconSpritesheetComposerView', () => {
expect(requestUpload).toHaveBeenCalledWith('icon-spec');
});
+ it('uses a grey hint instead of default icon text for new icon drafts', () => {
+ render(
+ ,
+ );
+
+ const input = screen.getByLabelText('素材描述') as HTMLTextAreaElement;
+ expect(input.value).toBe('');
+ expect(input.placeholder).toBe('你需要哪些图标?');
+ });
+
it('keeps the spec reference as a single first-row card without extra source buttons', () => {
render();
diff --git a/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.tsx b/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.tsx
index 2f984da58..360ca7732 100644
--- a/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.tsx
+++ b/src/components/image-editor/ImageCanvasIconSpritesheetComposerView.tsx
@@ -63,8 +63,7 @@ export function ImageCanvasIconSpritesheetComposerView({
onSubmit,
}: ImageCanvasIconSpritesheetComposerViewProps) {
const descriptionText =
- dialog.prompt ||
- (dialog.iconDescriptions ?? DEFAULT_ICON_DESCRIPTIONS).join('\n');
+ dialog.prompt || (dialog.iconDescriptions ?? []).join('\n');
useImageCanvasFloatingOptionDismiss({
isOpen: isIconSpecMenuOpen,
boundaryRefs: [iconSpecButtonRef],
@@ -176,7 +175,7 @@ export function ImageCanvasIconSpritesheetComposerView({
aria-label="素材描述"
value={descriptionText}
disabled={dialog.status === 'generating'}
- placeholder="描述要生成的多个素材,每行一个。"
+ placeholder="你需要哪些图标?"
size="sm"
density="compact"
className="image-canvas-editor__generation-prompt image-canvas-editor__generation-prompt--borderless"
diff --git a/src/components/image-editor/ImageCanvasSpecGenerationPanelView.test.tsx b/src/components/image-editor/ImageCanvasSpecGenerationPanelView.test.tsx
index b4fb4bf76..0df94fd83 100644
--- a/src/components/image-editor/ImageCanvasSpecGenerationPanelView.test.tsx
+++ b/src/components/image-editor/ImageCanvasSpecGenerationPanelView.test.tsx
@@ -161,6 +161,13 @@ describe('ImageCanvasSpecGenerationPanelView', () => {
onUpdateSpecFormValue: updateSpecFormValue,
});
+ expect(
+ (screen.getByLabelText('玩法设定') as HTMLInputElement).placeholder,
+ ).toBe('这是什么类型的游戏?');
+ expect(
+ (screen.getByLabelText('美术风格') as HTMLInputElement).placeholder,
+ ).toBe('游戏的画风是怎样的?');
+
fireEvent.change(screen.getByLabelText('玩法设定'), {
target: { value: '战棋玩法' },
});
@@ -183,6 +190,34 @@ describe('ImageCanvasSpecGenerationPanelView', () => {
);
});
+ it('uses gameplay and art style hints for icon specs', () => {
+ renderPanel({
+ dialog: createSpecDialog({
+ specType: 'ui',
+ specValues: {
+ playSetting: '',
+ artStyle: '',
+ bodyRatio: '3',
+ characterView: '右向斜侧身站姿',
+ customPrompt: '',
+ },
+ }),
+ });
+
+ expect((screen.getByLabelText('玩法设定') as HTMLInputElement).value).toBe(
+ '',
+ );
+ expect(
+ (screen.getByLabelText('玩法设定') as HTMLInputElement).placeholder,
+ ).toBe('这是什么类型的游戏?');
+ expect((screen.getByLabelText('美术风格') as HTMLInputElement).value).toBe(
+ '',
+ );
+ expect(
+ (screen.getByLabelText('美术风格') as HTMLInputElement).placeholder,
+ ).toBe('游戏的画风是怎样的?');
+ });
+
it('renders custom prompt and hides reference upload for icon specs', () => {
const updateSpecFormValue = vi.fn();
renderPanel({
@@ -199,6 +234,13 @@ describe('ImageCanvasSpecGenerationPanelView', () => {
onUpdateSpecFormValue: updateSpecFormValue,
});
+ const customPrompt = screen.getByLabelText(
+ '自定义规范提示词',
+ ) as HTMLTextAreaElement;
+ expect(customPrompt.placeholder).toBe(
+ '写下你想要的任何内容,陶泥儿帮你形成新的约束',
+ );
+
fireEvent.change(screen.getByLabelText('自定义规范提示词'), {
target: { value: '新的规范提示' },
});
diff --git a/src/components/image-editor/ImageCanvasSpecGenerationPanelView.tsx b/src/components/image-editor/ImageCanvasSpecGenerationPanelView.tsx
index 79158b7b2..fcb12a296 100644
--- a/src/components/image-editor/ImageCanvasSpecGenerationPanelView.tsx
+++ b/src/components/image-editor/ImageCanvasSpecGenerationPanelView.tsx
@@ -60,6 +60,10 @@ type ImageCanvasSpecGenerationPanelViewProps = {
onSubmit: (dialog: GenerateDialogState) => void;
};
+function shouldShowSpecInputPlaceholders(dialog: GenerateDialogState) {
+ return dialog.specType === 'character' || dialog.specType === 'ui';
+}
+
export function ImageCanvasSpecGenerationPanelView({
dialog,
style,
@@ -77,6 +81,7 @@ export function ImageCanvasSpecGenerationPanelView({
onSubmit,
}: ImageCanvasSpecGenerationPanelViewProps) {
const isUiDesignDialog = dialog.mode === 'ui-design';
+ const showSpecInputPlaceholders = shouldShowSpecInputPlaceholders(dialog);
const specSizeLabel = resolveEditorImageSizeLabel({
aspectRatio: SPEC_GENERATION_ASPECT_RATIO,
imageSize: SPEC_GENERATION_IMAGE_SIZE,
@@ -237,6 +242,7 @@ export function ImageCanvasSpecGenerationPanelView({
variant="textarea"
aria-label="自定义规范提示词"
value={dialog.specValues?.customPrompt ?? ''}
+ placeholder="写下你想要的任何内容,陶泥儿帮你形成新的约束"
disabled={isGenerating}
size="sm"
density="compact"
@@ -258,6 +264,11 @@ export function ImageCanvasSpecGenerationPanelView({