fix(canvas): 保护生成中与失败节点画幅尺寸,支持变体即时持久化与 2K 分辨率高亮 (#359)
Co-authored-by: Danborad <danborad@github.com>
This commit is contained in:
1 parent
76e5a166dc
commit
8d9ab03a66
10 files changed
+127
-77
No files matched your search
@@ -17,11 +17,34 @@ export function fitNodeSize(width: number, height: number, maxWidth = 720, maxHe
|
||||
export function nodeSizeFromRatio(size: string, baseWidth: number, baseHeight: number) {
|
||||
const raw = String(size || "").trim();
|
||||
if (!raw || raw.toLowerCase() === "auto") return null;
|
||||
// 支持 16:9 / 1024x576 / 16:9-2k
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
const match = raw.match(/^(\d+(?:\.\d+)?)(?:x|:)(\d+(?:\.\d+)?)/i);
|
||||
if (!match) return null;
|
||||
const width = Number(match[1]);
|
||||
const height = Number(match[2]);
|
||||
if (match) {
|
||||
width = Number(match[1]);
|
||||
height = Number(match[2]);
|
||||
} else if (raw.includes("竖") || raw.includes("portrait") || raw.includes("9:16")) {
|
||||
width = 9;
|
||||
height = 16;
|
||||
} else if (raw.includes("横") || raw.includes("landscape") || raw.includes("16:9")) {
|
||||
width = 16;
|
||||
height = 9;
|
||||
} else if (raw.includes("(1:1)") || raw.includes("1:1") || raw.includes("square")) {
|
||||
width = 1;
|
||||
height = 1;
|
||||
} else if (raw.includes("3:4")) {
|
||||
width = 3;
|
||||
height = 4;
|
||||
} else if (raw.includes("4:3")) {
|
||||
width = 4;
|
||||
height = 3;
|
||||
} else if (raw.includes("2:3")) {
|
||||
width = 2;
|
||||
height = 3;
|
||||
} else if (raw.includes("3:2")) {
|
||||
width = 3;
|
||||
height = 2;
|
||||
}
|
||||
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;
|
||||
const ratio = width / Math.max(1, height);
|
||||
if (ratio < 0.25 || ratio > 4) return { width: baseWidth, height: baseHeight };
|
||||
@@ -35,14 +58,22 @@ export function ensureMediaNodeMinimumSize(node: CanvasNodeData) {
|
||||
let width = node.width;
|
||||
let height = node.height;
|
||||
const emptyStage = isBuiltinCanvasNodeType(node.type) ? NODE_DEFAULT_SIZE[node.type] : undefined;
|
||||
const shouldPromoteEmptyStage = !node.metadata?.content
|
||||
&& !node.metadata?.freeResize
|
||||
&& !node.metadata?.locked
|
||||
&& emptyStage !== undefined
|
||||
&& width * height < emptyStage.width * emptyStage.height;
|
||||
if (shouldPromoteEmptyStage) {
|
||||
width = emptyStage.width;
|
||||
height = emptyStage.height;
|
||||
|
||||
// 如果未完成节点(生成中/失败/空节点)指定了目标比例(如 3:4, 9:16),按目标比例保持占位框尺寸,不能强制变成 16:9 横屏。
|
||||
const targetSize = node.metadata?.size ? nodeSizeFromRatio(node.metadata.size, emptyStage?.width || 720, emptyStage?.height || 405) : null;
|
||||
if (targetSize && !node.metadata?.content && !node.metadata?.freeResize && !node.metadata?.locked) {
|
||||
width = targetSize.width;
|
||||
height = targetSize.height;
|
||||
} else {
|
||||
const shouldPromoteEmptyStage = !node.metadata?.content
|
||||
&& !node.metadata?.freeResize
|
||||
&& !node.metadata?.locked
|
||||
&& emptyStage !== undefined
|
||||
&& (width <= 0 || height <= 0);
|
||||
if (shouldPromoteEmptyStage) {
|
||||
width = emptyStage.width;
|
||||
height = emptyStage.height;
|
||||
}
|
||||
}
|
||||
const naturalWidth = node.metadata?.naturalWidth || 0;
|
||||
const naturalHeight = node.metadata?.naturalHeight || 0;
|
||||
|
||||
Reference in new issue
Block a user