fix: 场景裂变页面保留顶部工具栏

- 修改 ImageAnnotator 布局,使顶部工具栏在场景裂变模式下始终可见
- 将 SceneFusionView 嵌入到工具栏下方的工作区
- 隐藏 SceneFusionView 自带的顶部标题栏
- 优化场景裂变按钮的交互逻辑
This commit is contained in:
Your Name 2026-01-18 15:39:34 +08:00
parent f4e20cc4c8
commit b238a26e85
2 changed files with 50 additions and 36 deletions

View File

@ -1216,15 +1216,7 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
className="fixed inset-0 z-[9999] flex items-center justify-center bg-background" className="fixed inset-0 z-[9999] flex items-center justify-center bg-background"
onClick={onCancel} onClick={onCancel}
> >
{showSceneFusion ? ( {/* 弹窗容器 - 全屏显示 */}
<div
className="w-full h-full bg-background"
onClick={(e) => e.stopPropagation()}
>
<SceneFusionView onBack={() => setShowSceneFusion(false)} />
</div>
) : (
/* 弹窗容器 - 全屏显示 */
<div <div
className="flex flex-col overflow-hidden w-full h-full" className="flex flex-col overflow-hidden w-full h-full"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
@ -1254,7 +1246,7 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={handleRemoveBackground} onClick={handleRemoveBackground}
disabled={isRemovingBg || isEnhancing || isExtending || isResizeMode || showAngleEditDialog || !image} disabled={isRemovingBg || isEnhancing || isExtending || isResizeMode || showAngleEditDialog || showSceneFusion || !image}
title="移除背景(抠图)" title="移除背景(抠图)"
> >
<Scissors className={`mr-1 h-4 w-4 ${isRemovingBg ? "animate-spin" : ""}`} /> <Scissors className={`mr-1 h-4 w-4 ${isRemovingBg ? "animate-spin" : ""}`} />
@ -1264,7 +1256,7 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={handleEnhance} onClick={handleEnhance}
disabled={isEnhancing || isRemovingBg || isExtending || isResizeMode || showAngleEditDialog || !image} disabled={isEnhancing || isRemovingBg || isExtending || isResizeMode || showAngleEditDialog || showSceneFusion || !image}
title="图片变清晰" title="图片变清晰"
> >
<Sparkles className={`mr-1 h-4 w-4 ${isEnhancing ? "animate-spin" : ""}`} /> <Sparkles className={`mr-1 h-4 w-4 ${isEnhancing ? "animate-spin" : ""}`} />
@ -1274,7 +1266,7 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={handleExtend} onClick={handleExtend}
disabled={isExtending || isRemovingBg || isEnhancing || isResizeMode || showAngleEditDialog || !image} disabled={isExtending || isRemovingBg || isEnhancing || isResizeMode || showAngleEditDialog || showSceneFusion || !image}
title="图像拓展" title="图像拓展"
> >
<Expand className={`mr-1 h-4 w-4 ${isExtending ? "animate-spin" : ""}`} /> <Expand className={`mr-1 h-4 w-4 ${isExtending ? "animate-spin" : ""}`} />
@ -1284,7 +1276,7 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={handleResize} onClick={handleResize}
disabled={isResizeMode || isRemovingBg || isEnhancing || isExtending || showAngleEditDialog || !image} disabled={isResizeMode || isRemovingBg || isEnhancing || isExtending || showAngleEditDialog || showSceneFusion || !image}
title="尺寸调整" title="尺寸调整"
> >
<Maximize2 className="mr-1 h-4 w-4" /> <Maximize2 className="mr-1 h-4 w-4" />
@ -1294,45 +1286,64 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={handleAngleEdit} onClick={handleAngleEdit}
disabled={showAngleEditDialog || isRemovingBg || isEnhancing || isExtending || isResizeMode || !image} disabled={showAngleEditDialog || isRemovingBg || isEnhancing || isExtending || isResizeMode || showSceneFusion || !image}
title="角度调整" title="角度调整"
> >
<Move3D className="mr-1 h-4 w-4" /> <Move3D className="mr-1 h-4 w-4" />
角度调整 角度调整
</Button> </Button>
<Button <Button
variant="ghost" variant={showSceneFusion ? "secondary" : "ghost"}
size="sm" size="sm"
onClick={() => setShowSceneFusion(true)} onClick={() => {
disabled={showSceneFusion || showAngleEditDialog || isRemovingBg || isEnhancing || isExtending || isResizeMode} setShowSceneFusion(!showSceneFusion);
// 进入场景裂变时,退出其他模式
if (!showSceneFusion) {
setIsResizeMode(false);
setShowAngleEditDialog(false);
}
}}
disabled={showAngleEditDialog || isRemovingBg || isEnhancing || isExtending || isResizeMode}
title="场景裂变" title="场景裂变"
> >
<Layers className="mr-1 h-4 w-4" /> <Layers className="mr-1 h-4 w-4" />
场景裂变 场景裂变
</Button> </Button>
<Button variant="ghost" size="sm" onClick={handleUndo} disabled={actions.length === 0}> {!showSceneFusion && (
<Undo className="mr-1 h-4 w-4" /> <>
撤销 <Button variant="ghost" size="sm" onClick={handleUndo} disabled={actions.length === 0}>
</Button> <Undo className="mr-1 h-4 w-4" />
<Button variant="ghost" size="sm" onClick={handleClear} disabled={actions.length === 0}> 撤销
<Trash2 className="mr-1 h-4 w-4" /> </Button>
清空 <Button variant="ghost" size="sm" onClick={handleClear} disabled={actions.length === 0}>
</Button> <Trash2 className="mr-1 h-4 w-4" />
清空
</Button>
</>
)}
<Button variant="ghost" size="sm" onClick={onCancel}> <Button variant="ghost" size="sm" onClick={onCancel}>
<X className="mr-1 h-4 w-4" /> <X className="mr-1 h-4 w-4" />
取消 取消
</Button> </Button>
<Button size="sm" onClick={handleConfirm} className="bg-primary text-primary-foreground hover:bg-primary/90"> {!showSceneFusion && (
<Check className="mr-1 h-4 w-4" /> <Button size="sm" onClick={handleConfirm} className="bg-primary text-primary-foreground hover:bg-primary/90">
发送到新对话 <Check className="mr-1 h-4 w-4" />
</Button> 发送到新对话
</Button>
)}
</div> </div>
</div> </div>
{/* 工具选择栏 / 尺寸调整工具栏 */} {showSceneFusion ? (
{isResizeMode ? ( <div className="flex-1 overflow-hidden relative">
/* 尺寸调整模式下显示尺寸调整工具栏 */ <SceneFusionView onBack={() => setShowSceneFusion(false)} />
<div className="flex flex-col gap-3 border-b px-4 py-3 bg-muted/30"> </div>
) : (
<>
{/* 工具选择栏 / 尺寸调整工具栏 */}
{isResizeMode ? (
/* 尺寸调整模式下显示尺寸调整工具栏 */
<div className="flex flex-col gap-3 border-b px-4 py-3 bg-muted/30">
{/* 比例选择和尺寸输入在同一行 */} {/* 比例选择和尺寸输入在同一行 */}
<div className="flex items-center gap-4 flex-wrap"> <div className="flex items-center gap-4 flex-wrap">
{/* 比例选择 */} {/* 比例选择 */}
@ -1708,8 +1719,9 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel, initialResizeMod
</> </>
)} )}
</div> </div>
</>
)}
</div> </div>
)}
{/* 文字输入弹窗 */} {/* 文字输入弹窗 */}
{textPosition && ( {textPosition && (

View File

@ -304,7 +304,8 @@ export function SceneFusionView({ onBack }: SceneFusionViewProps) {
return ( return (
<div className="flex flex-col w-full h-full bg-background"> <div className="flex flex-col w-full h-full bg-background">
{/* 顶部标题栏 */} {/* 顶部标题栏 - 已在外部显示,此处隐藏 */
/*
<div className="flex items-center justify-between border-b px-4 py-3 shrink-0"> <div className="flex items-center justify-between border-b px-4 py-3 shrink-0">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Button variant="ghost" size="icon" onClick={onBack} title="返回图片编辑"> <Button variant="ghost" size="icon" onClick={onBack} title="返回图片编辑">
@ -318,8 +319,9 @@ export function SceneFusionView({ onBack }: SceneFusionViewProps) {
<div className="text-sm text-muted-foreground hidden md:block"> <div className="text-sm text-muted-foreground hidden md:block">
上传1张产品图和多张场景图,AI 自动将产品融合到所有场景中 上传1张产品图和多张场景图,AI 自动将产品融合到所有场景中
</div> </div>
<div className="w-10"></div>{/* 占位,保持标题居中 */} <div className="w-10"></div>
</div> </div>
*/}
<div className="flex-1 overflow-hidden flex flex-col md:flex-row"> <div className="flex-1 overflow-hidden flex flex-col md:flex-row">
{/* 左侧:输入区域 */} {/* 左侧:输入区域 */}