完善快速编辑参考图与生成占位

- 快速编辑支持最多8张额外参考图,并将原图自动作为最后一张参考图提交

- 快速编辑尺寸和模型沿用原图配置,按禁用态参数胶囊展示

- 快速编辑提交前同步改写原图引用为实际图序号

- 快速编辑生成改为创建独立画布生成占位,并支持键盘删除生成中对象

- 对齐生成类面板参考图图标、规范类固定参数和相关文档测试
This commit is contained in:
2026-06-18 22:39:03 +08:00
parent b04b6cee2b
commit ea29887d9c
65 changed files with 2819 additions and 531 deletions
@@ -6,6 +6,7 @@ import type {
} from './ImageCanvasEditorTypes';
import {
createAudioResultLayer,
createCharacterAnimationResultLayer,
createGeneratedResultLayer,
createIconSpritesheetResultLayers,
createQuickEditResultLayer,
@@ -71,14 +72,14 @@ describe('ImageCanvasGenerationLayerModel', () => {
originalHeight: 1152,
},
assetKind: 'spec',
title: 'UI素材规范 7',
title: '图标规范 7',
generationInputs: createGenerationInputs(),
});
expect(layer).toMatchObject({
id: 'layer-generated-7',
resourceId: 'local-resource-generated-7',
title: 'UI素材规范 7',
title: '图标规范 7',
x: -664,
y: -358.5,
width: 2048,
@@ -120,6 +121,32 @@ describe('ImageCanvasGenerationLayerModel', () => {
});
});
it('creates quick edit layers centered on the generating placeholder', () => {
const sourceLayer = createSourceLayer();
const layer = createQuickEditResultLayer({
generated: createGenerated({ width: 1536, height: 1024 }),
generatedIndex: 10,
sourceLayer,
generationInputs: createGenerationInputs(),
frame: {
x: 600,
y: 300,
width: 320,
height: 240,
originalWidth: 1536,
originalHeight: 1024,
},
});
expect(layer).toMatchObject({
id: 'layer-quick-edit-10',
x: -8,
y: -92,
width: 1536,
height: 1024,
});
});
it('creates quick edit layers with source group and asset kind preserved', () => {
const sourceLayer = createSourceLayer();
const layer = createQuickEditResultLayer({
@@ -278,4 +305,66 @@ describe('ImageCanvasGenerationLayerModel', () => {
taskId: 'sound-task-1',
});
});
it('creates character animation result layers with action metadata', () => {
const layer = createCharacterAnimationResultLayer({
generated: {
taskId: 'character-animation-task-1',
model: 'seedance2.0-fast',
prompt: '待机动作',
previewVideoPath: '/generated-character-drafts/editor/preview.mp4',
frames: [
{
frameIndex: 1,
imageSrc: '/generated-character-drafts/editor/frame1.png',
width: 1024,
height: 1024,
},
],
frameCount: 32,
durationSeconds: 4,
fps: 8,
priceMudPoints: 40,
},
generatedIndex: 15,
title: '角色动作',
canvasSize: { width: 900, height: 640 },
viewport: { x: 10, y: 20, scale: 2 },
frame: {
x: 80,
y: 60,
width: 420,
height: 420,
originalWidth: 1024,
originalHeight: 1024,
},
generationInputs: {
fields: [{ title: '动作描述', value: '待机动作' }],
references: [],
},
});
expect(layer).toMatchObject({
id: 'layer-character-animation-15',
resourceId: 'local-resource-character-animation-15',
title: '角色动作',
src: '/generated-character-drafts/editor/frame1.png',
x: -222,
y: -242,
width: 1024,
height: 1024,
originalWidth: 1024,
originalHeight: 1024,
zIndex: 25,
sourceType: 'generated',
prompt: '待机动作',
actualPrompt: '待机动作',
model: 'seedance2.0-fast',
provider: 'ark',
taskId: 'character-animation-task-1',
assetKind: 'character-animation',
});
expect(layer?.mediaType).toBeUndefined();
expect(layer?.generationInputs?.fields[0]?.value).toBe('待机动作');
});
});