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

View File

@ -304,7 +304,8 @@ export function SceneFusionView({ onBack }: SceneFusionViewProps) {
return (
<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 gap-2">
<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">
上传1张产品图和多张场景图,AI 自动将产品融合到所有场景中
</div>
<div className="w-10"></div>{/* 占位,保持标题居中 */}
<div className="w-10"></div>
</div>
*/}
<div className="flex-1 overflow-hidden flex flex-col md:flex-row">
{/* 左侧:输入区域 */}