refactor: beautify realtime enhance workspace ui
This commit is contained in:
parent
8fec20b3be
commit
a17a035689
@ -101,27 +101,34 @@ const FALLBACK_CONFIG: EnhanceProClientConfig = {
|
||||
};
|
||||
|
||||
const PANEL_SHELL_CLASS =
|
||||
"pointer-events-auto rounded-[28px] border border-[#e7e1d4] bg-white/88 shadow-[0_20px_50px_rgba(15,23,42,0.08)] backdrop-blur-xl";
|
||||
"pointer-events-auto rounded-[24px] border border-[#e0e2e8] bg-white shadow-[0_0_0_1px_rgb(224,226,232),0_16px_36px_rgba(28,28,30,0.04)]";
|
||||
const SOLID_PANEL_FIELD_CLASS =
|
||||
"border-[#e7e1d4] bg-[#fffdfa] text-foreground shadow-[0_8px_20px_rgba(15,23,42,0.05)]";
|
||||
"border-[#e9eaef] bg-white text-[#1c1c1e] shadow-[0_1px_2px_rgba(28,28,30,0.04)]";
|
||||
const SOLID_PANEL_CARD_CLASS =
|
||||
"rounded-[22px] border border-[#e7e1d4] bg-[#fffdfa] shadow-[0_8px_20px_rgba(15,23,42,0.05)]";
|
||||
const PANEL_SECTION_TITLE_CLASS = "font-semibold text-[12px] text-slate-700";
|
||||
const PANEL_SECTION_NOTE_CLASS = "text-[10.5px] leading-4 text-slate-500";
|
||||
"rounded-[20px] border border-[#e0e2e8] bg-white shadow-[0_0_0_1px_rgb(224,226,232),0_8px_18px_rgba(28,28,30,0.03)]";
|
||||
const PANEL_SECTION_TITLE_CLASS =
|
||||
"font-semibold text-[12px] tracking-[-0.02em] text-[#1c1c1e]";
|
||||
const PANEL_SECTION_NOTE_CLASS =
|
||||
"text-[11px] leading-4 text-[#555a6a]";
|
||||
const SOLID_PANEL_SELECT_CONTENT_CLASS =
|
||||
"border-[#e7e1d4] bg-[#fffdfa] shadow-[0_16px_34px_rgba(15,23,42,0.08)]";
|
||||
"border-[#e0e2e8] bg-white shadow-[0_0_0_1px_rgb(224,226,232),0_16px_34px_rgba(28,28,30,0.08)]";
|
||||
const PRIMARY_ACTION_BUTTON_CLASS =
|
||||
"border border-[#2563eb] bg-[#2563eb] text-white shadow-[0_10px_22px_rgba(37,99,235,0.18)] transition hover:border-[#1d4ed8] hover:bg-[#1d4ed8] disabled:border-[#e7e1d4] disabled:bg-slate-200 disabled:text-slate-500 disabled:shadow-none";
|
||||
"border border-[#5b76fe] bg-[#5b76fe] text-white shadow-[0_14px_28px_rgba(91,118,254,0.24)] transition hover:border-[#2a41b6] hover:bg-[#2a41b6] disabled:border-[#e0e2e8] disabled:bg-[#eef1f6] disabled:text-[#a5a8b5] disabled:shadow-none";
|
||||
const SECONDARY_ACTION_BUTTON_CLASS =
|
||||
"border border-[#d8e4ff] bg-[#eef4ff] text-[#1d4ed8] shadow-[0_8px_20px_rgba(59,130,246,0.10)] transition hover:bg-[#e4eeff] hover:text-[#1e40af] disabled:border-[#e7e1d4] disabled:bg-slate-100 disabled:text-slate-400 disabled:shadow-none";
|
||||
const COMPACT_FIELD_CLASS = `${SOLID_PANEL_FIELD_CLASS} h-10 rounded-[16px] text-sm`;
|
||||
const COMPACT_LABEL_CLASS = "text-slate-600 text-[11px] leading-4";
|
||||
"border border-[#c7cad5] bg-white text-[#1c1c1e] shadow-[0_0_0_1px_rgb(224,226,232),0_8px_18px_rgba(28,28,30,0.03)] transition hover:border-[#5b76fe] hover:bg-[#f6f8ff] hover:text-[#2a41b6] disabled:border-[#e0e2e8] disabled:bg-[#f7f8fb] disabled:text-[#a5a8b5] disabled:shadow-none";
|
||||
const COMPACT_FIELD_CLASS = `${SOLID_PANEL_FIELD_CLASS} h-11 rounded-[16px] text-sm`;
|
||||
const COMPACT_LABEL_CLASS =
|
||||
"font-medium text-[#555a6a] text-[11px] leading-4";
|
||||
const COMPACT_TOGGLE_CARD_CLASS =
|
||||
"flex items-center justify-between gap-2.5 px-3 py-2.5";
|
||||
const SLIDER_TRACK_CLASS = "h-2 bg-[#ece7da] shadow-inner";
|
||||
const SLIDER_RANGE_CLASS = "bg-[#3b82f6]";
|
||||
const SLIDER_TRACK_CLASS = "h-2 bg-[#edf0f5] shadow-inner";
|
||||
const SLIDER_RANGE_CLASS = "bg-[#5b76fe]";
|
||||
const SLIDER_THUMB_CLASS =
|
||||
"h-4 w-4 border border-[#d8e4ff] bg-white shadow-[0_0_0_4px_rgba(59,130,246,0.16)]";
|
||||
"h-4 w-4 border border-[#c7cad5] bg-white shadow-[0_0_0_4px_rgba(91,118,254,0.16)]";
|
||||
const SIDEBAR_SCROLL_CLASS =
|
||||
"pr-1.5 [scrollbar-width:thin] [scrollbar-color:#d7cfbf_transparent] [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-[#d7cfbf] hover:[&::-webkit-scrollbar-thumb]:bg-[#c8bda9]";
|
||||
const SIDEBAR_SECTION_CARD_CLASS =
|
||||
"rounded-[22px] border border-[#ece3d4] bg-[#fffdf8] p-3.5 shadow-[0_10px_24px_rgba(15,23,42,0.05)]";
|
||||
|
||||
function clampNumber(value: number, min: number, max: number) {
|
||||
return Math.min(max, Math.max(min, value));
|
||||
@ -636,8 +643,8 @@ export function EnhanceProWorkspace({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative flex h-full w-full bg-background text-foreground">
|
||||
<div className="relative flex min-w-0 flex-1 items-center justify-center overflow-hidden bg-muted/20 pb-24">
|
||||
<div className="relative flex h-full w-full bg-white text-[#1c1c1e]">
|
||||
<div className="relative flex min-w-0 flex-1 items-center justify-center overflow-hidden bg-[radial-gradient(circle_at_16%_16%,rgba(91,118,254,0.09),transparent_26%),radial-gradient(circle_at_84%_20%,rgba(255,230,205,0.65),transparent_18%),radial-gradient(circle_at_72%_86%,rgba(195,250,245,0.55),transparent_20%),#ffffff] pb-24">
|
||||
{activePreviewUrl ? (
|
||||
<div
|
||||
className={cn(
|
||||
@ -658,18 +665,20 @@ export function EnhanceProWorkspace({
|
||||
transform: `translate(${previewOffset.x}px, ${previewOffset.y}px)`,
|
||||
}}
|
||||
/>
|
||||
<div className="pointer-events-none absolute top-6 left-6 flex items-center gap-2 rounded-full border border-[#e7e1d4] bg-[#fffdfa]/95 px-3 py-1.5 text-muted-foreground text-xs shadow-sm backdrop-blur-sm">
|
||||
<div className="pointer-events-none absolute top-6 left-6 flex items-center gap-2 rounded-full border border-[#e0e2e8] bg-white/92 px-3 py-1.5 text-[#555a6a] text-xs shadow-[0_0_0_1px_rgb(224,226,232),0_10px_24px_rgba(28,28,30,0.04)] backdrop-blur-sm">
|
||||
<ImageIcon className="h-3.5 w-3.5" />
|
||||
<span>{activePreviewLabel}</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex max-w-md flex-col items-center gap-3 px-6 text-center">
|
||||
<Sparkles className="h-10 w-10 text-muted-foreground/35" />
|
||||
<div className="font-semibold text-foreground text-lg">
|
||||
<div className="flex max-w-[28rem] flex-col items-center gap-4 rounded-[28px] border border-[#e0e2e8] bg-white/92 px-8 py-9 text-center shadow-[0_0_0_1px_rgb(224,226,232),0_24px_48px_rgba(28,28,30,0.05)] backdrop-blur-sm">
|
||||
<div className="flex h-16 w-16 items-center justify-center rounded-[22px] bg-[#eef2ff] text-[#5b76fe] shadow-[0_8px_18px_rgba(91,118,254,0.16)]">
|
||||
<Sparkles className="h-8 w-8" />
|
||||
</div>
|
||||
<div className="font-semibold text-[30px] tracking-[-0.03em] text-[#1c1c1e] leading-[1.08]">
|
||||
还没有可增强的图片
|
||||
</div>
|
||||
<div className="text-muted-foreground text-sm leading-6">
|
||||
<div className="max-w-[24rem] text-[#555a6a] text-[15px] leading-7">
|
||||
请先在主画布中选中一张图片,再从底部工具栏进入“图像增强 Pro”,
|
||||
或者先在实时画布模式里生成一张结果后再切回来。
|
||||
</div>
|
||||
@ -678,7 +687,7 @@ export function EnhanceProWorkspace({
|
||||
|
||||
{generatedImages.length > 0 && sidePreviewItems.length > 0 ? (
|
||||
<div className="absolute right-6 bottom-28 left-6 flex items-center justify-center">
|
||||
<div className="flex max-w-[min(720px,calc(100vw-5rem))] items-center gap-2 rounded-[24px] border border-[#e7e1d4] bg-[#fffdfa]/95 px-3 py-3 shadow-xl backdrop-blur-sm">
|
||||
<div className="flex max-w-[min(720px,calc(100vw-5rem))] items-center gap-2 rounded-[24px] border border-[#e0e2e8] bg-white/94 px-3 py-3 shadow-[0_0_0_1px_rgb(224,226,232),0_20px_40px_rgba(28,28,30,0.05)] backdrop-blur-sm">
|
||||
{sidePreviewItems.map((item, index) => {
|
||||
const isActive = item.isSource
|
||||
? selectedResultIndex < 0
|
||||
@ -688,8 +697,8 @@ export function EnhanceProWorkspace({
|
||||
className={cn(
|
||||
"group flex h-16 w-16 shrink-0 overflow-hidden rounded-2xl border transition",
|
||||
isActive
|
||||
? "border-sky-500 shadow-[0_0_0_1px_rgba(14,165,233,0.18)]"
|
||||
: "border-[#e7e1d4] hover:shadow-sm"
|
||||
? "border-[#5b76fe] shadow-[0_0_0_1px_rgba(91,118,254,0.18),0_10px_20px_rgba(91,118,254,0.12)]"
|
||||
: "border-[#e0e2e8] hover:shadow-sm"
|
||||
)}
|
||||
key={item.key}
|
||||
onClick={() =>
|
||||
@ -711,7 +720,7 @@ export function EnhanceProWorkspace({
|
||||
) : null}
|
||||
|
||||
<div className="pointer-events-none absolute bottom-5 left-1/2 z-30 flex w-fit max-w-[calc(100%-2rem)] -translate-x-1/2 flex-col items-center gap-1.5">
|
||||
<div className="pointer-events-auto rounded-full border border-[#e7e1d4] bg-[#fffdfa]/95 px-3.5 py-1 text-muted-foreground text-[11px] shadow-lg backdrop-blur-xl">
|
||||
<div className="pointer-events-auto rounded-full border border-[#e0e2e8] bg-white/94 px-3.5 py-1 text-[#555a6a] text-[11px] shadow-[0_0_0_1px_rgb(224,226,232),0_10px_22px_rgba(28,28,30,0.04)] backdrop-blur-xl">
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
{selectedGeneratedImage ? (
|
||||
<CheckCircle2 className="h-3.5 w-3.5 text-emerald-600" />
|
||||
@ -719,7 +728,7 @@ export function EnhanceProWorkspace({
|
||||
{actionHint}
|
||||
</span>
|
||||
</div>
|
||||
<div className="pointer-events-auto inline-flex items-center justify-center gap-2 rounded-full border border-[#e7e1d4] bg-[#fffdfa]/95 p-1.5 shadow-2xl backdrop-blur-xl">
|
||||
<div className="pointer-events-auto inline-flex items-center justify-center gap-2 rounded-full border border-[#e0e2e8] bg-white/94 p-1.5 shadow-[0_0_0_1px_rgb(224,226,232),0_16px_32px_rgba(28,28,30,0.06)] backdrop-blur-xl">
|
||||
<Button
|
||||
className={cn(
|
||||
"h-10 min-w-[208px] rounded-full px-5 text-sm",
|
||||
@ -753,8 +762,8 @@ export function EnhanceProWorkspace({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 h-full w-[412px] max-w-[41vw] shrink-0 py-5 pr-5">
|
||||
<div className="h-full space-y-3 overflow-y-auto pr-1 pb-3">
|
||||
<div className="relative z-20 h-full w-[408px] max-w-[40vw] shrink-0 py-5 pr-5">
|
||||
<div className="h-full space-y-3 overflow-y-auto pr-2 pb-3 [scrollbar-color:#c9d2ea_transparent] [scrollbar-width:thin] [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-[#c9d2ea] [&::-webkit-scrollbar-thumb]:border-[2px] [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:border-transparent">
|
||||
{isLoading ? (
|
||||
<div
|
||||
className={cn(
|
||||
@ -787,10 +796,15 @@ export function EnhanceProWorkspace({
|
||||
>
|
||||
<CollapsibleTrigger asChild>
|
||||
<button
|
||||
className="flex w-full items-center justify-between gap-3 text-left"
|
||||
className="flex w-full items-center justify-between gap-3 rounded-[18px] bg-[#f7f8fc] px-3 py-2.5 text-left transition hover:bg-[#f1f4fb]"
|
||||
type="button"
|
||||
>
|
||||
<div className={PANEL_SECTION_TITLE_CLASS}>设置</div>
|
||||
<div className="space-y-0.5">
|
||||
<div className="text-[10px] font-semibold tracking-[0.14em] text-[#555a6a] uppercase">
|
||||
Studio
|
||||
</div>
|
||||
<div className={PANEL_SECTION_TITLE_CLASS}>设置</div>
|
||||
</div>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 text-slate-500 transition-transform",
|
||||
@ -815,9 +829,11 @@ export function EnhanceProWorkspace({
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{selectedPreset ? (
|
||||
<div className={cn(PANEL_SECTION_NOTE_CLASS, "line-clamp-2")}>
|
||||
<div className="rounded-[18px] border border-[#e7ebf4] bg-[#f7f8fc] px-3 py-2.5">
|
||||
<div className={cn(PANEL_SECTION_NOTE_CLASS, "line-clamp-2")}>
|
||||
{selectedPreset.description ||
|
||||
`${selectedPreset.model} · ${getSubjectDetectionLabel(selectedPreset.subjectDetection)}`}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@ -830,7 +846,7 @@ export function EnhanceProWorkspace({
|
||||
增强提示词
|
||||
</Label>
|
||||
<Textarea
|
||||
className={`${SOLID_PANEL_FIELD_CLASS} min-h-[72px] resize-none rounded-[18px] text-sm placeholder:text-muted-foreground/70`}
|
||||
className={`${SOLID_PANEL_FIELD_CLASS} min-h-[76px] resize-none rounded-[18px] bg-[#fbfcff] text-sm placeholder:text-[#a5a8b5]`}
|
||||
id="enhance-workspace-prompt"
|
||||
onChange={(event) =>
|
||||
setFormState((prev) => ({
|
||||
@ -1047,7 +1063,8 @@ export function EnhanceProWorkspace({
|
||||
<div
|
||||
className={cn(
|
||||
SOLID_PANEL_CARD_CLASS,
|
||||
COMPACT_TOGGLE_CARD_CLASS
|
||||
COMPACT_TOGGLE_CARD_CLASS,
|
||||
"bg-[#fbfcff]"
|
||||
)}
|
||||
>
|
||||
<span className="text-foreground text-xs">启用放大</span>
|
||||
@ -1064,7 +1081,8 @@ export function EnhanceProWorkspace({
|
||||
<div
|
||||
className={cn(
|
||||
SOLID_PANEL_CARD_CLASS,
|
||||
COMPACT_TOGGLE_CARD_CLASS
|
||||
COMPACT_TOGGLE_CARD_CLASS,
|
||||
"bg-[#fbfcff]"
|
||||
)}
|
||||
>
|
||||
<span className="text-foreground text-xs">裁剪铺满</span>
|
||||
@ -1090,10 +1108,15 @@ export function EnhanceProWorkspace({
|
||||
>
|
||||
<CollapsibleTrigger asChild>
|
||||
<button
|
||||
className="flex w-full items-center justify-between gap-3 text-left"
|
||||
className="flex w-full items-center justify-between gap-3 rounded-[18px] bg-[#f7f8fc] px-3 py-2.5 text-left transition hover:bg-[#f1f4fb]"
|
||||
type="button"
|
||||
>
|
||||
<div className={PANEL_SECTION_TITLE_CLASS}>调节</div>
|
||||
<div className="space-y-0.5">
|
||||
<div className="text-[10px] font-semibold tracking-[0.14em] text-[#555a6a] uppercase">
|
||||
Adjust
|
||||
</div>
|
||||
<div className={PANEL_SECTION_TITLE_CLASS}>调节</div>
|
||||
</div>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 text-slate-500 transition-transform",
|
||||
@ -1176,10 +1199,15 @@ export function EnhanceProWorkspace({
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<CollapsibleTrigger asChild>
|
||||
<button
|
||||
className="flex min-w-0 flex-1 items-center justify-between gap-3 text-left"
|
||||
className="flex min-w-0 flex-1 items-center justify-between gap-3 rounded-[18px] bg-[#f7f8fc] px-3 py-2.5 text-left transition hover:bg-[#f1f4fb]"
|
||||
type="button"
|
||||
>
|
||||
<div className={PANEL_SECTION_TITLE_CLASS}>面部增强</div>
|
||||
<div className="space-y-0.5">
|
||||
<div className="text-[10px] font-semibold tracking-[0.14em] text-[#555a6a] uppercase">
|
||||
Face
|
||||
</div>
|
||||
<div className={PANEL_SECTION_TITLE_CLASS}>面部增强</div>
|
||||
</div>
|
||||
<ChevronDown
|
||||
className={cn(
|
||||
"h-4 w-4 shrink-0 text-slate-500 transition-transform",
|
||||
|
||||
@ -2918,17 +2918,17 @@ export function RealtimeCanvasDialog({
|
||||
}, [clearPreviewCanvas, closeBrushSettingPopovers, resetCanvas]);
|
||||
|
||||
const floatingSurfaceClass =
|
||||
"border border-[#e7e1d4] bg-white/88 shadow-[0_18px_40px_rgba(15,23,42,0.08)] backdrop-blur-xl";
|
||||
"border border-[#e0e2e8] bg-white/92 shadow-[0_0_0_1px_rgb(224,226,232),0_16px_36px_rgba(28,28,30,0.05)] backdrop-blur-xl";
|
||||
const controlSurfaceClass =
|
||||
"border border-[#e7e1d4] bg-[#fffdfa] text-foreground shadow-[0_8px_20px_rgba(15,23,42,0.05)]";
|
||||
"border border-[#e9eaef] bg-white text-[#1c1c1e] shadow-[0_1px_2px_rgba(28,28,30,0.04)]";
|
||||
const softActionButtonClass =
|
||||
"border border-[#d8e4ff] bg-[#eef4ff] text-[#1d4ed8] shadow-[0_8px_20px_rgba(59,130,246,0.10)] transition hover:bg-[#e4eeff] hover:text-[#1e40af]";
|
||||
"border border-[#dbe2ff] bg-[#eef2ff] text-[#5b76fe] shadow-[0_10px_20px_rgba(91,118,254,0.10)] transition hover:bg-[#e7ecff] hover:text-[#2a41b6]";
|
||||
const primaryActionButtonClass =
|
||||
"border border-[#2563eb] bg-[#2563eb] text-white shadow-[0_10px_22px_rgba(37,99,235,0.18)] transition hover:border-[#1d4ed8] hover:bg-[#1d4ed8]";
|
||||
"border border-[#5b76fe] bg-[#5b76fe] text-white shadow-[0_14px_28px_rgba(91,118,254,0.22)] transition hover:border-[#2a41b6] hover:bg-[#2a41b6]";
|
||||
const compactToolButtonClass =
|
||||
"h-9 w-9 rounded-[16px] border border-transparent text-slate-600 transition hover:border-[#d8e4ff] hover:bg-[#eef4ff] hover:text-[#1d4ed8]";
|
||||
"h-9 w-9 rounded-[16px] border border-transparent text-[#555a6a] transition hover:border-[#dbe2ff] hover:bg-[#eef2ff] hover:text-[#5b76fe]";
|
||||
const compactToolButtonActiveClass =
|
||||
"border-[#d8e4ff] bg-[#eef4ff] text-[#1d4ed8] shadow-[0_6px_16px_rgba(59,130,246,0.12)] hover:bg-[#e4eeff] hover:text-[#1d4ed8]";
|
||||
"border-[#dbe2ff] bg-[#eef2ff] text-[#5b76fe] shadow-[0_8px_18px_rgba(91,118,254,0.14)] hover:bg-[#e7ecff] hover:text-[#5b76fe]";
|
||||
const currentModeLabel =
|
||||
brushMode === "select"
|
||||
? "鼠标"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user