Fix canvas persistence and reference sizing

This commit is contained in:
Codex
2026-05-11 19:16:32 +08:00
parent e3454c7fba
commit 6db64d5161
3 changed files with 23 additions and 2 deletions

View File

@@ -509,6 +509,18 @@ function getNodeImageUrl(node?: CanvasNode | null) {
return node.selectedOutput || node.outputImages?.[0] || '';
}
function getNodeImageDimensions(node?: CanvasNode | null) {
if (!node) return {};
const imageWidth = typeof node.imageWidth === 'number' && node.imageWidth > 0 ? node.imageWidth : undefined;
const imageHeight = typeof node.imageHeight === 'number' && node.imageHeight > 0 ? node.imageHeight : undefined;
if (imageWidth && imageHeight) return { width: imageWidth, height: imageHeight };
const previewHeight = Math.max(1, node.height - 80);
return {
width: Math.max(1, Math.round(node.width)),
height: Math.max(1, Math.round(previewHeight)),
};
}
function getNodeTextValue(node?: CanvasNode | null) {
if (!node || node.type !== 'text') return '';
return node.text?.trim() || '';
@@ -1555,6 +1567,8 @@ export function InfiniteCanvasWorkspace() {
addNode('image', point?.x ?? 120, point?.y ?? 120, {
title: file.name || '图片',
imageUrl: dataUrl,
imageWidth: dimensions.width,
imageHeight: dimensions.height,
width: Math.min(520, Math.max(260, (dimensions.width || 600) / 2)),
height: Math.min(520, Math.max(240, (dimensions.height || 420) / 2 + 80)),
});
@@ -1683,6 +1697,9 @@ export function InfiniteCanvasWorkspace() {
const incomingPromptText = incomingNodes.map(getNodeTextValue).filter(Boolean).join('\n');
const incomingImageNode = incomingNodes.find(item => !!getNodeImageUrl(item));
const referenceImage = node.referenceImage || getNodeImageUrl(incomingImageNode);
const referenceDimensions = node.referenceImage
? canvasState.nodes.find(item => getNodeImageUrl(item) === node.referenceImage)
: incomingImageNode;
const basePrompt = node.prompt?.trim() || '';
const prompt = incomingPromptText
? [incomingPromptText, basePrompt].filter(Boolean).join('\n\n')
@@ -1709,8 +1726,9 @@ export function InfiniteCanvasWorkspace() {
if (shouldUseReferenceImage) {
payload.image = referenceImage;
payload.strength = node.params?.strength ?? 0.5;
const { width: referenceWidth, height: referenceHeight } = getNodeImageDimensions(referenceDimensions || node);
payload.size = aspectRatio === 'original'
? resolveImageSizeFromDimensions(undefined, undefined, resolution)
? resolveImageSizeFromDimensions(referenceWidth, referenceHeight, resolution)
: isExternal
? resolveCustomApiImageSize(aspectRatio, resolution)
: resolveImageSize(aspectRatio, resolution);

View File

@@ -13,6 +13,7 @@ export function normalizeCanvasState(value: unknown): CanvasProjectState {
return {
nodes: Array.isArray(value.nodes) ? value.nodes as CanvasProjectState['nodes'] : [],
connections: Array.isArray(value.connections) ? value.connections as CanvasProjectState['connections'] : [],
groups: Array.isArray(value.groups) ? value.groups as CanvasProjectState['groups'] : [],
assets: Array.isArray(value.assets) ? value.assets as CanvasProjectState['assets'] : [],
viewport: {
x: typeof viewport.x === 'number' ? viewport.x : 0,
@@ -30,7 +31,7 @@ export async function ensureCanvasSchema() {
id uuid PRIMARY KEY,
user_id uuid NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
title text NOT NULL DEFAULT '未命名画布',
state jsonb NOT NULL DEFAULT '{"nodes":[],"assets":[],"viewport":{"x":0,"y":0,"zoom":1}}'::jsonb,
state jsonb NOT NULL DEFAULT '{"nodes":[],"connections":[],"groups":[],"assets":[],"viewport":{"x":0,"y":0,"zoom":1}}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
)

View File

@@ -62,6 +62,8 @@ export type CanvasNode = {
negativePrompt?: string;
text?: string;
imageUrl?: string;
imageWidth?: number;
imageHeight?: number;
referenceImage?: string;
outputImages?: string[];
selectedOutput?: string;