fix: speed up psd editor image preview
This commit is contained in:
parent
19dc43049d
commit
6f4a881238
@ -400,6 +400,42 @@ function buildPsdLayerPreviewUrl(
|
||||
return buildTemplatePreviewThumbUrl(imageUrl, { width, quality });
|
||||
}
|
||||
|
||||
function buildAssignedPsdLayerPreviewFallbackUrls(
|
||||
imageUrl: string,
|
||||
params?: {
|
||||
width?: number;
|
||||
quality?: number;
|
||||
}
|
||||
) {
|
||||
const normalizedUrl = String(imageUrl || "").trim();
|
||||
if (!normalizedUrl) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const width = Math.max(96, Math.min(1280, Math.round(params?.width || 720)));
|
||||
const quality = Math.max(52, Math.min(82, Math.round(params?.quality || 74)));
|
||||
const directDisplayUrl = buildImageProxyUrl(normalizedUrl, {
|
||||
width,
|
||||
quality,
|
||||
format: "webp",
|
||||
});
|
||||
const proxyUrl = buildImageProxyUrl(normalizedUrl, {
|
||||
width,
|
||||
quality,
|
||||
format: "webp",
|
||||
delivery: "proxy",
|
||||
});
|
||||
const seen = new Set<string>();
|
||||
|
||||
return [normalizedUrl, directDisplayUrl, proxyUrl].filter((url) => {
|
||||
if (!url || seen.has(url)) {
|
||||
return false;
|
||||
}
|
||||
seen.add(url);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function buildPsdLayerMaskUrl(maskUrl: string, layerWidth: number) {
|
||||
const normalizedUrl = String(maskUrl || "").trim();
|
||||
if (!normalizedUrl) {
|
||||
@ -536,6 +572,72 @@ function TemplatePreviewImage({
|
||||
);
|
||||
}
|
||||
|
||||
function AssignedPsdLayerPreviewImage({
|
||||
sourceUrl,
|
||||
alt,
|
||||
className,
|
||||
width,
|
||||
quality,
|
||||
style,
|
||||
}: {
|
||||
sourceUrl: string;
|
||||
alt: string;
|
||||
className?: string;
|
||||
width?: number;
|
||||
quality?: number;
|
||||
style?: CSSProperties;
|
||||
}) {
|
||||
const fallbackUrls = useMemo(
|
||||
() => buildAssignedPsdLayerPreviewFallbackUrls(sourceUrl, { width, quality }),
|
||||
[quality, sourceUrl, width]
|
||||
);
|
||||
const fallbackUrlKey = fallbackUrls.join("\n");
|
||||
const [activeUrlIndex, setActiveUrlIndex] = useState(0);
|
||||
const [hasLoaded, setHasLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setActiveUrlIndex(0);
|
||||
setHasLoaded(false);
|
||||
}, [fallbackUrlKey]);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasLoaded || activeUrlIndex + 1 >= fallbackUrls.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
setActiveUrlIndex((current) =>
|
||||
current + 1 < fallbackUrls.length ? current + 1 : current
|
||||
);
|
||||
}, 6500);
|
||||
|
||||
return () => window.clearTimeout(timeoutId);
|
||||
}, [activeUrlIndex, fallbackUrls.length, hasLoaded]);
|
||||
|
||||
const src = fallbackUrls[activeUrlIndex] || "";
|
||||
if (!src) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
alt={alt}
|
||||
className={className}
|
||||
decoding="async"
|
||||
fetchPriority="high"
|
||||
loading="eager"
|
||||
onError={() =>
|
||||
setActiveUrlIndex((current) =>
|
||||
current + 1 < fallbackUrls.length ? current + 1 : current
|
||||
)
|
||||
}
|
||||
onLoad={() => setHasLoaded(true)}
|
||||
src={src}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function getScrollAreaViewportElement(root: HTMLDivElement | null) {
|
||||
return (
|
||||
(root?.querySelector(
|
||||
@ -4293,45 +4395,54 @@ export function AgentPsdTemplateEditorDialog({
|
||||
}}
|
||||
title={`${getLayerLabel(layer)}:${layer.layerName}`}
|
||||
>
|
||||
<img
|
||||
alt={layer.layerName}
|
||||
className={
|
||||
assignedUrl ? "" : "h-full w-full"
|
||||
}
|
||||
decoding="async"
|
||||
src={buildPsdLayerPreviewUrl(layerImageUrl, {
|
||||
width: assignedUrl
|
||||
? Math.max(layer.width, layer.height)
|
||||
: layer.width,
|
||||
quality: assignedUrl ? 74 : 68,
|
||||
delivery: assignedUrl ? "proxy" : undefined,
|
||||
})}
|
||||
style={
|
||||
assignedUrl && imageSizes[layer.id]
|
||||
? getPlacedAssignedImageStyle({
|
||||
layer,
|
||||
frameLayer: assignedFrameLayer,
|
||||
imageSize: imageSizes[layer.id],
|
||||
placement:
|
||||
effectiveImagePlacements[
|
||||
layer.id
|
||||
],
|
||||
})
|
||||
: assignedUrl
|
||||
? {
|
||||
{assignedUrl ? (
|
||||
<AssignedPsdLayerPreviewImage
|
||||
alt={layer.layerName}
|
||||
quality={74}
|
||||
sourceUrl={layerImageUrl}
|
||||
style={
|
||||
imageSizes[layer.id]
|
||||
? getPlacedAssignedImageStyle({
|
||||
layer,
|
||||
frameLayer: assignedFrameLayer,
|
||||
imageSize: imageSizes[layer.id],
|
||||
placement:
|
||||
effectiveImagePlacements[
|
||||
layer.id
|
||||
],
|
||||
})
|
||||
: {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: getImageFit(
|
||||
layer.replaceMode
|
||||
),
|
||||
}
|
||||
: {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "fill",
|
||||
}
|
||||
}
|
||||
/>
|
||||
}
|
||||
width={Math.max(
|
||||
layer.width,
|
||||
layer.height
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
alt={layer.layerName}
|
||||
className="h-full w-full"
|
||||
decoding="async"
|
||||
src={buildPsdLayerPreviewUrl(
|
||||
layerImageUrl,
|
||||
{
|
||||
width: layer.width,
|
||||
quality: 68,
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "fill",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user