fix: stack layer split results as full-frame overlays
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-24 03:55:52 +08:00
parent 8af70192f8
commit 33fcb34900

View File

@ -409,56 +409,6 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
}, [detailSubjectAnalysis, detailUiDslDocumentFromMetadata, detailUiScreenOverlay]);
const shouldRenderDetailOverlay =
data.metadata?.detailGenerationMode === "agent_layout" && Boolean(detailUiScreenOverlay);
const layerSplitBounds = useMemo<LayerSplitBounds | null>(() => {
const raw = data.metadata?.bounds;
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
const x = Number((raw as any).x);
const y = Number((raw as any).y);
const width = Number((raw as any).width);
const height = Number((raw as any).height);
const originalWidth = Number((raw as any).originalWidth);
const originalHeight = Number((raw as any).originalHeight);
const coverage = Number((raw as any).coverage);
if (
!Number.isFinite(x) ||
!Number.isFinite(y) ||
!Number.isFinite(width) ||
!Number.isFinite(height) ||
!Number.isFinite(originalWidth) ||
!Number.isFinite(originalHeight) ||
width <= 0 ||
height <= 0 ||
originalWidth <= 0 ||
originalHeight <= 0
) {
return null;
}
return {
x,
y,
width,
height,
originalWidth,
originalHeight,
coverage: Number.isFinite(coverage) ? coverage : 0,
};
}, [data.metadata]);
const layerSplitCropStyle = useMemo<React.CSSProperties | undefined>(() => {
if (!layerSplitBounds) return undefined;
return {
position: "absolute",
width: `${(layerSplitBounds.originalWidth / layerSplitBounds.width) * 100}%`,
height: `${(layerSplitBounds.originalHeight / layerSplitBounds.height) * 100}%`,
maxWidth: "none",
maxHeight: "none",
left: `${-(layerSplitBounds.x / layerSplitBounds.width) * 100}%`,
top: `${-(layerSplitBounds.y / layerSplitBounds.height) * 100}%`,
};
}, [layerSplitBounds]);
const shortAgentExecutionSnapshotId = agentExecutionSnapshotId
? agentExecutionSnapshotId.slice(0, 8)
: "";
@ -2291,29 +2241,11 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
const layerTitle = `${displayTitle}-${layer.title || `图层${layer.layerIndex || index + 1}`}`;
const bounds = layer.bounds;
const fullFrameLayer = isFullFrameLayer(bounds);
const hasUsableBounds =
bounds &&
bounds.originalWidth > 0 &&
bounds.originalHeight > 0 &&
bounds.width > 0 &&
bounds.height > 0;
const scaleX = hasUsableBounds ? node.size.width / bounds.originalWidth : 1;
const scaleY = hasUsableBounds ? node.size.height / bounds.originalHeight : 1;
const targetPosition = hasUsableBounds && !fullFrameLayer
? {
x: node.position.x + groupOffsetX + bounds.x * scaleX,
y: node.position.y + groupOffsetY + bounds.y * scaleY,
}
: {
x: node.position.x + groupOffsetX,
y: node.position.y + groupOffsetY,
};
const targetSize = hasUsableBounds && !fullFrameLayer
? {
width: Math.max(1, bounds.width * scaleX),
height: Math.max(1, bounds.height * scaleY),
}
: { width: node.size.width, height: node.size.height };
const targetPosition = {
x: node.position.x + groupOffsetX,
y: node.position.y + groupOffsetY,
};
const targetSize = { width: node.size.width, height: node.size.height };
addNode({
type: "image",
@ -2731,12 +2663,9 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
src={displayImageSrc}
alt={displayTitle}
className={cn(
layerSplitCropStyle
? "absolute bg-transparent"
: "w-full h-full object-contain bg-muted/30",
"w-full h-full object-contain bg-muted/30",
boxCutoutMode ? "cursor-crosshair" : isThisNodePicking ? "cursor-crosshair" : "cursor-pointer"
)}
style={layerSplitCropStyle}
draggable={false}
loading="lazy"
decoding="async"