feat: Improve the data input and submission acquisition of SD parameter panel

This commit is contained in:
licoy 2024-07-02 15:19:44 +08:00
parent bbbf59c74a
commit 7fde9327a2
3 changed files with 145 additions and 22 deletions

View File

@ -13,6 +13,18 @@ const sdCommonParams = (model: string, data: any) => {
placeholder: locales.SdPanel.PleaseInput(locales.SdPanel.Prompt), placeholder: locales.SdPanel.PleaseInput(locales.SdPanel.Prompt),
required: true, required: true,
}, },
{
name: locales.SdPanel.ChildModel,
value: "model",
type: "select",
default: 0,
support: ["sd3"],
options: [
{ name: "SD3 Medium", value: "sd3-medium" },
{ name: "SD3 Large", value: "sd3-large" },
{ name: "SD3 Large Turbo", value: "sd3-large-turbo" },
],
},
{ {
name: locales.SdPanel.NegativePrompt, name: locales.SdPanel.NegativePrompt,
value: "negative_prompt", value: "negative_prompt",
@ -26,7 +38,14 @@ const sdCommonParams = (model: string, data: any) => {
default: "1:1", default: "1:1",
options: [ options: [
{ name: "1:1", value: "1:1" }, { name: "1:1", value: "1:1" },
{ name: "2:2", value: "2:2" }, { name: "16:9", value: "16:9" },
{ name: "21:9", value: "21:9" },
{ name: "2:3", value: "2:3" },
{ name: "3:2", value: "3:2" },
{ name: "4:5", value: "4:5" },
{ name: "5:4", value: "5:4" },
{ name: "9:16", value: "9:16" },
{ name: "9:21", value: "9:21" },
], ],
}, },
{ {
@ -35,9 +54,37 @@ const sdCommonParams = (model: string, data: any) => {
type: "select", type: "select",
default: "3d", default: "3d",
support: ["core"], support: ["core"],
options: [{ name: "3D", value: "3d" }], options: [
{ name: locales.SdPanel.Styles.D3Model, value: "3d-model" },
{ name: locales.SdPanel.Styles.AnalogFilm, value: "analog-film" },
{ name: locales.SdPanel.Styles.Anime, value: "anime" },
{ name: locales.SdPanel.Styles.Cinematic, value: "cinematic" },
{ name: locales.SdPanel.Styles.ComicBook, value: "comic-book" },
{ name: locales.SdPanel.Styles.DigitalArt, value: "digital-art" },
{ name: locales.SdPanel.Styles.Enhance, value: "enhance" },
{ name: locales.SdPanel.Styles.FantasyArt, value: "fantasy-art" },
{ name: locales.SdPanel.Styles.Isometric, value: "isometric" },
{ name: locales.SdPanel.Styles.LineArt, value: "line-art" },
{ name: locales.SdPanel.Styles.LowPoly, value: "low-poly" },
{
name: locales.SdPanel.Styles.ModelingCompound,
value: "modeling-compound",
},
{ name: locales.SdPanel.Styles.NeonPunk, value: "neon-punk" },
{ name: locales.SdPanel.Styles.Origami, value: "origami" },
{ name: locales.SdPanel.Styles.Photographic, value: "photographic" },
{ name: locales.SdPanel.Styles.PixelArt, value: "pixel-art" },
{ name: locales.SdPanel.Styles.TileTexture, value: "tile-texture" },
],
},
{
name: "Seed",
value: "seed",
type: "number",
default: 0,
min: 0,
max: 4294967294,
}, },
{ name: "Seed", value: "seed", type: "number", default: 0 },
{ {
name: locales.SdPanel.OutFormat, name: locales.SdPanel.OutFormat,
value: "output_format", value: "output_format",
@ -69,7 +116,11 @@ const models = [
name: "Stable Diffusion 3", name: "Stable Diffusion 3",
value: "sd3", value: "sd3",
params: (data: any) => { params: (data: any) => {
return sdCommonParams("sd3", data); return sdCommonParams("sd3", data).filter((item) => {
return !(
data.model === "sd3-large-turbo" && item.value == "negative_prompt"
);
});
}, },
}, },
]; ];
@ -100,15 +151,8 @@ export function ControlParamItem(props: {
export function ControlParam(props: { export function ControlParam(props: {
columns: any[]; columns: any[];
data: any; data: any;
set: React.Dispatch<React.SetStateAction<{}>>; onChange: (field: string, val: any) => void;
}) { }) {
const handleValueChange = (field: string, val: any) => {
props.set((prevParams) => ({
...prevParams,
[field]: val,
}));
};
return ( return (
<> <>
{props.columns.map((item) => { {props.columns.map((item) => {
@ -122,7 +166,7 @@ export function ControlParam(props: {
style={{ maxWidth: "100%", width: "100%", padding: "10px" }} style={{ maxWidth: "100%", width: "100%", padding: "10px" }}
placeholder={item.placeholder} placeholder={item.placeholder}
onChange={(e) => { onChange={(e) => {
handleValueChange(item.value, e.currentTarget.value); props.onChange(item.value, e.currentTarget.value);
}} }}
value={props.data[item.value]} value={props.data[item.value]}
></textarea> ></textarea>
@ -135,7 +179,7 @@ export function ControlParam(props: {
<Select <Select
value={props.data[item.value]} value={props.data[item.value]}
onChange={(e) => { onChange={(e) => {
handleValueChange(item.value, e.currentTarget.value); props.onChange(item.value, e.currentTarget.value);
}} }}
> >
{item.options.map((opt: any) => { {item.options.map((opt: any) => {
@ -154,9 +198,11 @@ export function ControlParam(props: {
<ControlParamItem title={item.name} subTitle={item.sub}> <ControlParamItem title={item.name} subTitle={item.sub}>
<input <input
type="number" type="number"
value={props.data[item.value]} min={item.min}
max={item.max}
value={props.data[item.value] || 0}
onChange={(e) => { onChange={(e) => {
handleValueChange(item.value, e.currentTarget.value); props.onChange(item.value, parseInt(e.currentTarget.value));
}} }}
/> />
</ControlParamItem> </ControlParamItem>
@ -170,7 +216,7 @@ export function ControlParam(props: {
value={props.data[item.value]} value={props.data[item.value]}
style={{ maxWidth: "100%", width: "100%" }} style={{ maxWidth: "100%", width: "100%" }}
onChange={(e) => { onChange={(e) => {
handleValueChange(item.value, e.currentTarget.value); props.onChange(item.value, e.currentTarget.value);
}} }}
/> />
</ControlParamItem> </ControlParamItem>
@ -182,9 +228,47 @@ export function ControlParam(props: {
); );
} }
const getModelParamBasicData = (
columns: any[],
data: any,
clearText?: boolean,
) => {
const newParams: any = {};
columns.forEach((item: any) => {
if (clearText && ["text", "textarea", "number"].includes(item.type)) {
newParams[item.value] = item.default || "";
} else {
// @ts-ignore
newParams[item.value] = data[item.value] || item.default || "";
}
});
return newParams;
};
export function SdPanel() { export function SdPanel() {
const [currentModel, setCurrentModel] = useState(models[0]); const [currentModel, setCurrentModel] = useState(models[0]);
const [params, setParams] = useState({}); const [params, setParams] = useState(
getModelParamBasicData(currentModel.params({}), {}),
);
const handleValueChange = (field: string, val: any) => {
setParams((prevParams: any) => ({
...prevParams,
[field]: val,
}));
};
const handleModelChange = (model: any) => {
setCurrentModel(model);
setParams(getModelParamBasicData(model.params({}), params));
};
const handleSubmit = () => {
const columns = currentModel.params(params);
const reqData: any = {};
columns.forEach((item: any) => {
reqData[item.value] = params[item.value] ?? null;
});
console.log(JSON.stringify(reqData, null, 4));
setParams(getModelParamBasicData(columns, params, true));
};
return ( return (
<> <>
<ControlParamItem title={locales.SdPanel.AIModel}> <ControlParamItem title={locales.SdPanel.AIModel}>
@ -196,9 +280,7 @@ export function SdPanel() {
key={item.value} key={item.value}
type={currentModel.value == item.value ? "primary" : null} type={currentModel.value == item.value ? "primary" : null}
shadow shadow
onClick={() => { onClick={() => handleModelChange(item)}
setCurrentModel(item);
}}
/> />
); );
})} })}
@ -206,14 +288,15 @@ export function SdPanel() {
</ControlParamItem> </ControlParamItem>
<ControlParam <ControlParam
columns={currentModel.params(params) as any[]} columns={currentModel.params(params) as any[]}
set={setParams}
data={params} data={params}
onChange={handleValueChange}
></ControlParam> ></ControlParam>
<IconButton <IconButton
text={locales.SdPanel.Submit} text={locales.SdPanel.Submit}
type="primary" type="primary"
style={{ marginTop: "20px" }} style={{ marginTop: "20px" }}
shadow shadow
onClick={handleSubmit}
></IconButton> ></IconButton>
</> </>
); );

View File

@ -492,7 +492,27 @@ const cn = {
ImageStyle: "图像风格", ImageStyle: "图像风格",
OutFormat: "输出格式", OutFormat: "输出格式",
AIModel: "AI模型", AIModel: "AI模型",
ChildModel: "子模型",
Submit: "提交生成", Submit: "提交生成",
Styles: {
D3Model: "3D模型",
AnalogFilm: "模拟电影",
Anime: "动漫",
Cinematic: "电影风格",
ComicBook: "漫画书",
DigitalArt: "数字艺术",
Enhance: "增强",
FantasyArt: "幻想艺术",
Isometric: "等角",
LineArt: "线描",
LowPoly: "低多边形",
ModelingCompound: "建模材料",
NeonPunk: "霓虹朋克",
Origami: "折纸",
Photographic: "摄影",
PixelArt: "像素艺术",
TileTexture: "贴图",
},
}, },
}; };

View File

@ -498,7 +498,27 @@ const en: LocaleType = {
ImageStyle: "Image Style", ImageStyle: "Image Style",
OutFormat: "Output Format", OutFormat: "Output Format",
AIModel: "AI Model", AIModel: "AI Model",
ChildModel: "Child Model",
Submit: "Submit", Submit: "Submit",
Styles: {
D3Model: "3d-model",
AnalogFilm: "analog-film",
Anime: "anime",
Cinematic: "cinematic",
ComicBook: "comic-book",
DigitalArt: "digital-art",
Enhance: "enhance",
FantasyArt: "fantasy-art",
Isometric: "isometric",
LineArt: "line-art",
LowPoly: "low-poly",
ModelingCompound: "modeling-compound",
NeonPunk: "neon-punk",
Origami: "origami",
Photographic: "photographic",
PixelArt: "pixel-art",
TileTexture: "tile-texture",
},
}, },
}; };