feat(project): init
This commit is contained in:
111
public/prompt-builder.js
Normal file
111
public/prompt-builder.js
Normal file
@@ -0,0 +1,111 @@
|
||||
export const STORAGE_KEY = "image-prompt-studio:simple-prompt:v1";
|
||||
|
||||
export const GENERATION_DEFAULTS = {
|
||||
size: "1024x1024",
|
||||
quality: "high",
|
||||
outputFormat: "png",
|
||||
background: "auto",
|
||||
count: 1,
|
||||
moderation: "auto",
|
||||
outputCompression: 90,
|
||||
};
|
||||
|
||||
export const EXAMPLE_PROMPTS = [
|
||||
"一只白色陶瓷杯放在浅灰色窗边桌面上,晨光柔和,极简产品摄影,干净背景,苹果官网质感。",
|
||||
"未来感电动车停在雾气很轻的海边公路,银色车身,阴天柔光,电影级写实海报。",
|
||||
"一间现代风格客厅,浅木地板,奶油白沙发,大面积自然光,室内设计杂志封面感。",
|
||||
"一款无线耳机悬浮在纯白背景中,蓝色柔和反射光,商业广告风,细节锐利。",
|
||||
];
|
||||
|
||||
export const PROCESSING_STAGES = [
|
||||
{
|
||||
title: "整理 Prompt",
|
||||
detail: "检查内容并准备发送到服务端。",
|
||||
thresholdMs: 1400,
|
||||
},
|
||||
{
|
||||
title: "连接 gpt-image-2",
|
||||
detail: "向 OpenAI Images API 发起图片生成请求。",
|
||||
thresholdMs: 5200,
|
||||
},
|
||||
{
|
||||
title: "等待渲染",
|
||||
detail: "模型正在生成高质量图片,这一步通常最耗时。",
|
||||
thresholdMs: 15000,
|
||||
},
|
||||
{
|
||||
title: "准备下载",
|
||||
detail: "接收 base64 图片并整理成浏览器可下载文件。",
|
||||
thresholdMs: 24000,
|
||||
},
|
||||
];
|
||||
|
||||
export function sanitizePrompt(input) {
|
||||
return String(input ?? "")
|
||||
.replace(/\r/g, "")
|
||||
.replace(/[ \t]+\n/g, "\n")
|
||||
.replace(/\n{3,}/g, "\n\n")
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.join("\n")
|
||||
.trim();
|
||||
}
|
||||
|
||||
export function buildPromptStats(prompt) {
|
||||
const cleanPrompt = sanitizePrompt(prompt);
|
||||
|
||||
if (!cleanPrompt) {
|
||||
return "输入一句清晰的画面描述即可开始。";
|
||||
}
|
||||
|
||||
const lineCount = cleanPrompt.split("\n").length;
|
||||
const charCount = cleanPrompt.length;
|
||||
|
||||
return `${charCount} 个字符 · ${lineCount} 行`;
|
||||
}
|
||||
|
||||
export function buildDownloadStem(prompt) {
|
||||
const normalized = sanitizePrompt(prompt)
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\u4e00-\u9fa5\s-]/g, "")
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.slice(0, 48);
|
||||
|
||||
return normalized || "generated-image";
|
||||
}
|
||||
|
||||
export function createProcessingSnapshot(elapsedMs, isComplete = false) {
|
||||
if (isComplete) {
|
||||
return {
|
||||
progress: 1,
|
||||
activeStageIndex: PROCESSING_STAGES.length - 1,
|
||||
lead: "图片已生成完成,可以预览和下载。",
|
||||
};
|
||||
}
|
||||
|
||||
const safeElapsed = Math.max(0, elapsedMs);
|
||||
const finalThreshold =
|
||||
PROCESSING_STAGES[PROCESSING_STAGES.length - 1]?.thresholdMs ?? 24000;
|
||||
const progress = Math.min(0.92, safeElapsed / finalThreshold);
|
||||
const activeStageIndex = resolveActiveStageIndex(safeElapsed);
|
||||
const activeStage = PROCESSING_STAGES[activeStageIndex];
|
||||
|
||||
return {
|
||||
progress,
|
||||
activeStageIndex,
|
||||
lead: activeStage
|
||||
? `${activeStage.title}中... ${activeStage.detail}`
|
||||
: "正在处理,请稍候。",
|
||||
};
|
||||
}
|
||||
|
||||
function resolveActiveStageIndex(elapsedMs) {
|
||||
for (let index = PROCESSING_STAGES.length - 1; index >= 0; index -= 1) {
|
||||
if (elapsedMs >= PROCESSING_STAGES[index].thresholdMs) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user