183 lines
4.9 KiB
TypeScript
183 lines
4.9 KiB
TypeScript
import type { WebCanvasWorkflow, WebCommunityCase } from "../types";
|
|
import { ossAssets } from "./ossAssets";
|
|
|
|
const [rainNightImage, characterLookImage, skylineImage, labImage] = ossAssets.workflows.caseImages;
|
|
|
|
function createNodes(
|
|
title: string,
|
|
previewUrl: string,
|
|
model = "Seedance 2.0",
|
|
): WebCanvasWorkflow["nodes"] {
|
|
return [
|
|
{
|
|
id: "prompt",
|
|
kind: "prompt",
|
|
label: "提示词",
|
|
detail: title,
|
|
position: { x: 90, y: 120 },
|
|
},
|
|
{
|
|
id: "reference",
|
|
kind: "image",
|
|
label: "参考图",
|
|
detail: "社区分享的视觉锚点",
|
|
position: { x: 380, y: 70 },
|
|
previewUrl,
|
|
},
|
|
{
|
|
id: "motion",
|
|
kind: "model",
|
|
label: "镜头与运动",
|
|
detail: "推镜、摇移、节奏",
|
|
position: { x: 720, y: 170 },
|
|
},
|
|
{
|
|
id: "output",
|
|
kind: "output",
|
|
label: "视频输出",
|
|
detail: `${model} 预览渲染`,
|
|
position: { x: 1020, y: 100 },
|
|
},
|
|
];
|
|
}
|
|
|
|
function createEdges(): WebCanvasWorkflow["edges"] {
|
|
return [
|
|
{ id: "prompt-reference", source: "prompt", target: "reference", label: "参考", animated: true },
|
|
{ id: "reference-motion", source: "reference", target: "motion", label: "运动", animated: true },
|
|
{ id: "motion-output", source: "motion", target: "output", label: "生成", animated: true },
|
|
];
|
|
}
|
|
|
|
export const blankCanvasWorkflow: WebCanvasWorkflow = {
|
|
id: "workflow-blank",
|
|
version: 1,
|
|
title: "新建创作",
|
|
description: "从空白画布开始,直接进入节点式创作。",
|
|
source: "blank",
|
|
settings: {
|
|
model: "Seedance 2.0",
|
|
ratio: "16:9",
|
|
duration: "6s",
|
|
resolution: "720p",
|
|
},
|
|
nodes: [],
|
|
edges: [],
|
|
};
|
|
|
|
export const communityCases: WebCommunityCase[] = [
|
|
{
|
|
id: "case-01",
|
|
title: "雨夜推镜",
|
|
author: "Dave",
|
|
tag: "视频案例",
|
|
summary: "从街口推到人物面部,强调雨夜反光与情绪收束。",
|
|
imageUrl: rainNightImage,
|
|
workflow: {
|
|
id: "workflow-rain-night",
|
|
version: 1,
|
|
title: "雨夜推镜",
|
|
description: "城市雨夜案例,突出推镜和情绪转场。",
|
|
author: "Dave",
|
|
source: "community",
|
|
settings: {
|
|
model: "Seedance 2.0",
|
|
ratio: "16:9",
|
|
duration: "6s",
|
|
resolution: "720p",
|
|
},
|
|
nodes: createNodes("雨夜街巷,镜头从水面倒影推进到人物特写", rainNightImage),
|
|
edges: createEdges(),
|
|
},
|
|
},
|
|
{
|
|
id: "case-02",
|
|
title: "角色定妆",
|
|
author: "SuperXe",
|
|
tag: "角色案例",
|
|
summary: "把单张角色图扩展成可连续出片的角色工作流。",
|
|
imageUrl: characterLookImage,
|
|
workflow: {
|
|
id: "workflow-character-look",
|
|
version: 1,
|
|
title: "角色定妆",
|
|
description: "角色定妆与动作参考结合的社区模板。",
|
|
author: "SuperXe",
|
|
source: "community",
|
|
settings: {
|
|
model: "Seedance 2.0",
|
|
ratio: "9:16",
|
|
duration: "5s",
|
|
resolution: "720p",
|
|
},
|
|
nodes: createNodes("角色定妆,强调服装、姿态与近景表情", characterLookImage),
|
|
edges: createEdges(),
|
|
},
|
|
},
|
|
{
|
|
id: "case-03",
|
|
title: "天际奇境",
|
|
author: "OmniAI",
|
|
tag: "风景案例",
|
|
summary: "用广角风景做镜头进入,适合转场和开场片头。",
|
|
imageUrl: skylineImage,
|
|
workflow: {
|
|
id: "workflow-skyline",
|
|
version: 1,
|
|
title: "天际奇境",
|
|
description: "适合开场镜头的广角风景工作流。",
|
|
author: "OmniAI",
|
|
source: "community",
|
|
settings: {
|
|
model: "Seedance 2.0",
|
|
ratio: "16:9",
|
|
duration: "8s",
|
|
resolution: "1080p",
|
|
},
|
|
nodes: createNodes("风景开场,镜头缓慢推进到天际线", skylineImage),
|
|
edges: createEdges(),
|
|
},
|
|
},
|
|
{
|
|
id: "case-04",
|
|
title: "镜头实验室",
|
|
author: "Studio",
|
|
tag: "实验案例",
|
|
summary: "更适合拆解推拉摇移和节奏控制的实验模板。",
|
|
imageUrl: labImage,
|
|
workflow: {
|
|
id: "workflow-lab",
|
|
version: 1,
|
|
title: "镜头实验室",
|
|
description: "用于测试节奏、焦段和多段镜头拆解的模板。",
|
|
author: "Studio",
|
|
source: "community",
|
|
settings: {
|
|
model: "Seedance 2.0",
|
|
ratio: "16:9",
|
|
duration: "6s",
|
|
resolution: "720p",
|
|
},
|
|
nodes: createNodes("镜头实验,分镜更清晰,便于二次调整", labImage),
|
|
edges: createEdges(),
|
|
},
|
|
},
|
|
];
|
|
|
|
export function cloneWorkflow(input: WebCanvasWorkflow): WebCanvasWorkflow {
|
|
return {
|
|
...input,
|
|
nodes: input.nodes.map((node) => ({ ...node, position: { ...node.position } })),
|
|
edges: input.edges.map((edge) => ({ ...edge })),
|
|
settings: { ...input.settings },
|
|
};
|
|
}
|
|
|
|
export function createBlankWorkflow(title = "新建创作"): WebCanvasWorkflow {
|
|
return {
|
|
...cloneWorkflow(blankCanvasWorkflow),
|
|
id: `workflow-${Date.now()}`,
|
|
title,
|
|
};
|
|
}
|