fix: improve psd editor dialog layout
This commit is contained in:
parent
80db6cd48d
commit
6d281e950a
@ -39,6 +39,8 @@ import {
|
||||
} from "@/lib/agents/psd-template-config";
|
||||
|
||||
const fetcher = (url: string) => fetch(url, { cache: "no-store" }).then((res) => res.json());
|
||||
const PREVIEW_VIEWPORT_PADDING = 56;
|
||||
const PREVIEW_STAGE_MAX_SCALE = 0.82;
|
||||
|
||||
function createInitialState(template: AgentPsdTemplate | null, sourceImageUrl: string) {
|
||||
const imageAssignments: Record<string, string> = {};
|
||||
@ -309,12 +311,12 @@ export function AgentPsdTemplateEditorDialog({
|
||||
|
||||
const updateScale = () => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const availableWidth = Math.max(240, rect.width - 32);
|
||||
const availableHeight = Math.max(240, rect.height - 32);
|
||||
const availableWidth = Math.max(240, rect.width - PREVIEW_VIEWPORT_PADDING);
|
||||
const availableHeight = Math.max(240, rect.height - PREVIEW_VIEWPORT_PADDING);
|
||||
const nextScale = Math.min(
|
||||
availableWidth / Math.max(1, selectedTemplate.width),
|
||||
availableHeight / Math.max(1, selectedTemplate.height),
|
||||
1
|
||||
PREVIEW_STAGE_MAX_SCALE
|
||||
);
|
||||
setStageScale(Number.isFinite(nextScale) && nextScale > 0 ? nextScale : 1);
|
||||
};
|
||||
@ -469,11 +471,6 @@ export function AgentPsdTemplateEditorDialog({
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="rounded-xl border border-dashed border-white/15 bg-white/[0.02] p-3 text-xs leading-6 text-muted-foreground">
|
||||
操作方式更接近 PS:
|
||||
直接点击模板里的图片区域去替换图片,点击模板里的文字区域直接改现有文字。
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleRender}
|
||||
disabled={isRendering}
|
||||
@ -500,7 +497,7 @@ export function AgentPsdTemplateEditorDialog({
|
||||
</ScrollArea>
|
||||
</div>
|
||||
|
||||
<div className="min-h-0 border-b border-white/10 bg-[#09090b] p-5 xl:border-b-0 xl:border-r">
|
||||
<div className="flex min-h-0 flex-col border-b border-white/10 bg-[#09090b] p-5 xl:border-b-0 xl:border-r">
|
||||
<div className="mb-4 flex flex-wrap items-center gap-2">
|
||||
<div className="text-sm font-medium">模板画布编辑区</div>
|
||||
{selectedTemplate ? (
|
||||
@ -516,11 +513,11 @@ export function AgentPsdTemplateEditorDialog({
|
||||
|
||||
<div
|
||||
ref={previewViewportRef}
|
||||
className="relative flex h-full min-h-[520px] items-start justify-center overflow-auto rounded-2xl border border-white/10 bg-[#111114]"
|
||||
className="relative flex min-h-0 flex-1 items-center justify-center overflow-auto rounded-2xl border border-white/10 bg-[#111114] p-4"
|
||||
>
|
||||
{selectedTemplate ? (
|
||||
<div
|
||||
className="relative my-4"
|
||||
className="relative shrink-0"
|
||||
style={{
|
||||
width: selectedTemplate.width * stageScale,
|
||||
height: selectedTemplate.height * stageScale,
|
||||
@ -731,8 +728,9 @@ export function AgentPsdTemplateEditorDialog({
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="flex h-full min-h-0 flex-col gap-5">
|
||||
<div className="rounded-2xl border border-white/10 bg-white/[0.02] p-4">
|
||||
<ScrollArea className="h-full pr-3">
|
||||
<div className="flex min-h-full flex-col gap-5">
|
||||
<div className="rounded-2xl border border-white/10 bg-white/[0.02] p-4">
|
||||
{selectedImageLayer ? (
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
@ -744,7 +742,7 @@ export function AgentPsdTemplateEditorDialog({
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">{selectedImageLayer.layerPath}</div>
|
||||
<div className="overflow-hidden rounded-xl border border-white/10 bg-white/5">
|
||||
<div className="aspect-[4/3]">
|
||||
<div className="h-[220px]">
|
||||
{effectiveImageAssignments[selectedImageLayer.id] ? (
|
||||
<img
|
||||
src={effectiveImageAssignments[selectedImageLayer.id]}
|
||||
@ -843,50 +841,51 @@ export function AgentPsdTemplateEditorDialog({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="min-h-0 flex-1 rounded-2xl border border-white/10 bg-white/[0.02] p-4">
|
||||
<div className="mb-3 text-sm font-medium">导出结果</div>
|
||||
{renderedResultUrl ? (
|
||||
<div className="flex h-full min-h-0 flex-col justify-between gap-4">
|
||||
<div className="mx-auto w-full max-w-[280px] overflow-hidden rounded-2xl border border-white/10 bg-white/5">
|
||||
<div
|
||||
style={{
|
||||
aspectRatio: selectedTemplate
|
||||
? `${Math.max(1, selectedTemplate.width)} / ${Math.max(1, selectedTemplate.height)}`
|
||||
: "1 / 1",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={renderedResultUrl}
|
||||
alt="PSD 模板导出结果"
|
||||
className="h-full w-full object-contain"
|
||||
/>
|
||||
<div className="min-h-0 flex-1 rounded-2xl border border-white/10 bg-white/[0.02] p-4">
|
||||
<div className="mb-3 text-sm font-medium">导出结果</div>
|
||||
{renderedResultUrl ? (
|
||||
<div className="flex h-full min-h-0 flex-col justify-between gap-4">
|
||||
<div className="mx-auto w-full max-w-[240px] overflow-hidden rounded-2xl border border-white/10 bg-white/5">
|
||||
<div
|
||||
style={{
|
||||
aspectRatio: selectedTemplate
|
||||
? `${Math.max(1, selectedTemplate.width)} / ${Math.max(1, selectedTemplate.height)}`
|
||||
: "1 / 1",
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={renderedResultUrl}
|
||||
alt="PSD 模板导出结果"
|
||||
className="h-full w-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button onClick={handleDownload} className="w-full">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
下载结果图
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-full min-h-[220px] flex-col items-center justify-center rounded-2xl border border-dashed border-white/15 bg-white/[0.02] px-6 text-center">
|
||||
<div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5">
|
||||
{selectedTextLayer ? (
|
||||
<Type className="h-8 w-8 text-muted-foreground" />
|
||||
) : (
|
||||
<ImageIcon className="h-8 w-8 text-muted-foreground" />
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4 text-sm font-medium">还未导出成品图</div>
|
||||
<div className="mt-2 text-xs leading-6 text-muted-foreground">
|
||||
在模板画布里完成替换后,点击“应用模板并导出”,这里会显示最终图片。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button onClick={handleDownload} className="w-full">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
下载结果图
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-full min-h-[240px] flex-col items-center justify-center rounded-2xl border border-dashed border-white/15 bg-white/[0.02] px-6 text-center">
|
||||
<div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5">
|
||||
{selectedTextLayer ? (
|
||||
<Type className="h-8 w-8 text-muted-foreground" />
|
||||
) : (
|
||||
<ImageIcon className="h-8 w-8 text-muted-foreground" />
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4 text-sm font-medium">还未导出成品图</div>
|
||||
<div className="mt-2 text-xs leading-6 text-muted-foreground">
|
||||
在模板画布里完成替换后,点击“应用模板并导出”,这里会显示最终图片。
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user