fix: preserve psd clip mask layer stacking
This commit is contained in:
parent
74f2d052ac
commit
6674c22cdd
@ -2290,6 +2290,13 @@ export function AgentPsdTemplateEditorDialog({
|
||||
),
|
||||
[orderedVisiblePreviewLayers]
|
||||
);
|
||||
const renderPreviewSegments = useMemo(
|
||||
() =>
|
||||
(selectedTemplate?.renderSegments || []).filter((segment) =>
|
||||
Boolean(String(segment.url || "").trim())
|
||||
),
|
||||
[selectedTemplate?.renderSegments]
|
||||
);
|
||||
|
||||
const effectiveImageAssignments = useMemo(() => {
|
||||
const nextAssignments: Record<string, string> = {};
|
||||
@ -2315,6 +2322,35 @@ export function AgentPsdTemplateEditorDialog({
|
||||
|
||||
return nextAssignments;
|
||||
}, [editableImageLayers, imageAssignments, selectedTemplate, sourceImageUrl]);
|
||||
const hasVisibleAssignedPreviewImageLayer = useMemo(
|
||||
() =>
|
||||
orderedVisiblePreviewLayers.some(
|
||||
(layer) =>
|
||||
isAgentPsdImageLayerSlot(layer) &&
|
||||
Boolean(String(effectiveImageAssignments[layer.id] || "").trim())
|
||||
),
|
||||
[effectiveImageAssignments, orderedVisiblePreviewLayers]
|
||||
);
|
||||
const shouldUseRenderSegmentPreviewFallback =
|
||||
shouldShowCompositeFallback &&
|
||||
hasVisibleAssignedPreviewImageLayer &&
|
||||
hiddenLayerIds.length === 0 &&
|
||||
renderPreviewSegments.length > 0;
|
||||
const shouldShowRenderBasePreviewFallback =
|
||||
shouldShowCompositeFallback && !shouldUseRenderSegmentPreviewFallback;
|
||||
const getRenderSegmentPreviewZIndex = (
|
||||
segment: NonNullable<AgentPsdTemplate["renderSegments"]>[number]
|
||||
) => {
|
||||
const beforeLayerId = String(segment.beforeLayerId || "").trim();
|
||||
if (beforeLayerId) {
|
||||
return Math.max(
|
||||
1,
|
||||
(layerStackZIndexById.get(beforeLayerId) || PSD_LAYER_Z_INDEX_STEP) - 1
|
||||
);
|
||||
}
|
||||
|
||||
return (orderedPreviewLayers.length + 1) * PSD_LAYER_Z_INDEX_STEP;
|
||||
};
|
||||
const pendingAssignedPreviewLayerIds = useMemo(
|
||||
() =>
|
||||
orderedVisiblePreviewLayers
|
||||
@ -4379,7 +4415,7 @@ export function AgentPsdTemplateEditorDialog({
|
||||
transformOrigin: "top left",
|
||||
}}
|
||||
>
|
||||
{shouldShowCompositeFallback &&
|
||||
{shouldShowRenderBasePreviewFallback &&
|
||||
orderedVisiblePreviewLayers.length > 0 ? (
|
||||
<TemplatePreviewImage
|
||||
alt={`${selectedTemplate.name} 编辑底图`}
|
||||
@ -4393,6 +4429,27 @@ export function AgentPsdTemplateEditorDialog({
|
||||
width={960}
|
||||
/>
|
||||
) : null}
|
||||
{shouldUseRenderSegmentPreviewFallback
|
||||
? renderPreviewSegments.map((segment) => (
|
||||
<img
|
||||
alt={`${selectedTemplate.name} 分层底图`}
|
||||
className="pointer-events-none absolute inset-0 h-full w-full object-cover"
|
||||
decoding="async"
|
||||
key={`render-segment-preview-${segment.id}`}
|
||||
loading="eager"
|
||||
src={buildTemplatePreviewThumbUrl(
|
||||
segment.url,
|
||||
{
|
||||
width: 960,
|
||||
quality: 74,
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
zIndex: getRenderSegmentPreviewZIndex(segment),
|
||||
}}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
{orderedVisiblePreviewLayers.map((layer) => {
|
||||
@ -4410,6 +4467,13 @@ export function AgentPsdTemplateEditorDialog({
|
||||
height: layer.height,
|
||||
} satisfies CSSProperties;
|
||||
|
||||
if (
|
||||
shouldUseRenderSegmentPreviewFallback &&
|
||||
!layer.isEditable
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isAgentPsdImageLayerSlot(layer)) {
|
||||
const assignedUrl =
|
||||
effectiveImageAssignments[layer.id];
|
||||
|
||||
@ -845,6 +845,18 @@ export async function preparePsdTemplateRenderAssets(params: {
|
||||
.filter(isAgentPsdTemplateLayerUserEditable)
|
||||
.map((layer) => layer.layerId)
|
||||
);
|
||||
const clipMaskBoundaryByTemplateLayerId = new Map<string, string>();
|
||||
for (const layer of params.layers) {
|
||||
if (
|
||||
isAgentPsdImageLayerSlot(layer) &&
|
||||
isAgentPsdTemplateLayerUserEditable(layer) &&
|
||||
layer.forceClipMask &&
|
||||
layer.clipMaskLayerId &&
|
||||
layer.clipMaskLayerId !== layer.id
|
||||
) {
|
||||
clipMaskBoundaryByTemplateLayerId.set(layer.clipMaskLayerId, layer.id);
|
||||
}
|
||||
}
|
||||
|
||||
const nextLayers = [...params.layers];
|
||||
|
||||
@ -1041,15 +1053,21 @@ export async function preparePsdTemplateRenderAssets(params: {
|
||||
assetConcurrency,
|
||||
async (entry, index) => {
|
||||
const layerSlot = layerSlotByPsdLayerId.get(entry.layer.layerId);
|
||||
const clipMaskBoundaryLayerId =
|
||||
clipMaskBoundaryByTemplateLayerId.get(layerSlot?.id || "") ||
|
||||
clipMaskBoundaryByTemplateLayerId.get(entry.layer.id);
|
||||
const isEditableBoundary = layerSlot
|
||||
? isAgentPsdTemplateLayerUserEditable(layerSlot)
|
||||
: editableLayerIdSet.has(entry.layer.layerId);
|
||||
const isClipMaskBoundary = Boolean(clipMaskBoundaryLayerId);
|
||||
|
||||
if (isEditableBoundary) {
|
||||
if (isEditableBoundary || isClipMaskBoundary) {
|
||||
return {
|
||||
index,
|
||||
input: null,
|
||||
beforeLayerId: layerSlot?.id || "",
|
||||
beforeLayerId: isClipMaskBoundary
|
||||
? clipMaskBoundaryLayerId || ""
|
||||
: layerSlot?.id || "",
|
||||
editableBoundary: true,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user