feat: 图片工具栏改为纯图标模式,悬停显示功能名称

- 移除工具栏按钮的文字标签,只显示图标
- 使用 Tooltip 组件在鼠标悬停时显示功能名称
- 将下载和删除按钮从下拉菜单移到工具栏直接显示
- 工具栏更紧凑,视觉更简洁
This commit is contained in:
Your Name 2026-02-02 11:07:52 +08:00
parent ed71477f15
commit dbed4020c0

View File

@ -20,6 +20,7 @@ import {
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider } from "@/components/ui/tooltip";
import { toast } from "sonner"; import { toast } from "sonner";
import { useCanvasStore } from "@/store/canvas"; import { useCanvasStore } from "@/store/canvas";
import { imageGenerationService } from "@/services/canvas"; import { imageGenerationService } from "@/services/canvas";
@ -594,150 +595,178 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
{/* 工具栏使用 Portal 渲染到 body,避免被裁剪 */} {/* 工具栏使用 Portal 渲染到 body,避免被裁剪 */}
{isSelected && data.src && !isProcessing && typeof document !== 'undefined' && createPortal( {isSelected && data.src && !isProcessing && typeof document !== 'undefined' && createPortal(
<div <TooltipProvider delayDuration={200}>
className="fixed flex items-center gap-0.5 bg-white border border-gray-200 rounded-full shadow-xl px-3 py-1.5 z-[9999]" <div
style={{ className="fixed flex items-center gap-0.5 bg-white border border-gray-200 rounded-full shadow-xl px-2 py-1 z-[9999]"
top: getToolbarPosition().top, style={{
left: getToolbarPosition().left, top: getToolbarPosition().top,
transform: 'translateX(-50%)', left: getToolbarPosition().left,
pointerEvents: 'auto', transform: 'translateX(-50%)',
}} pointerEvents: 'auto',
onClick={(e) => e.stopPropagation()}
>
{/* 🆕 添加到对话 */}
<Button
variant="ghost"
size="sm"
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-blue-50 text-blue-600 hover:text-blue-700"
onClick={() => {
addPendingChatAttachment({
url: data.src!,
name: data.prompt || '画布图片',
contentType: 'image/jpeg',
});
toast.success('已添加到对话框');
}} }}
title="添加到对话框" onClick={(e) => e.stopPropagation()}
> >
<MessageSquarePlus className="h-4 w-4" /> {/* 添加到对话 */}
<span>对话</span> <Tooltip>
</Button> <TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 rounded-full hover:bg-blue-50 text-blue-600 hover:text-blue-700"
onClick={() => {
addPendingChatAttachment({
url: data.src!,
name: data.prompt || '画布图片',
contentType: 'image/jpeg',
});
toast.success('已添加到对话框');
}}
>
<MessageSquarePlus className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">添加到对话</TooltipContent>
</Tooltip>
{/* 分隔线 */} {/* 分隔线 */}
<div className="h-5 w-px bg-gray-200 mx-1" /> <div className="h-5 w-px bg-gray-200 mx-0.5" />
{/* 放大/高清 */} {/* 放大/高清 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" variant="ghost"
onClick={() => handleAction('enhance')} size="icon"
title="高清放大" className="h-8 w-8 rounded-full hover:bg-gray-100"
> onClick={() => handleAction('enhance')}
<span className="text-[10px] font-medium text-gray-500 border border-gray-300 rounded px-1">HD</span> >
<span>放大</span> <span className="text-[10px] font-medium text-gray-500 border border-gray-300 rounded px-1">HD</span>
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">高清放大</TooltipContent>
</Tooltip>
{/* 移除背景/抠图 */} {/* 移除背景/抠图 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" variant="ghost"
onClick={() => handleAction('rmbg')} size="icon"
title="移除背景" className="h-8 w-8 rounded-full hover:bg-gray-100"
> onClick={() => handleAction('rmbg')}
<Scissors className="h-4 w-4" /> >
<span>移除背景</span> <Scissors className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">移除背景</TooltipContent>
</Tooltip>
{/* 场景融合 */} {/* 场景融合 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" variant="ghost"
onClick={() => handleAction('scene-fusion')} size="icon"
title="场景融合" className="h-8 w-8 rounded-full hover:bg-gray-100"
> onClick={() => handleAction('scene-fusion')}
<Layers className="h-4 w-4" /> >
<span>场景</span> <Layers className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">场景融合</TooltipContent>
</Tooltip>
{/* 角度编辑 */} {/* 角度编辑 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" variant="ghost"
onClick={() => handleAction('angle')} size="icon"
title="角度编辑" className="h-8 w-8 rounded-full hover:bg-gray-100"
> onClick={() => handleAction('angle')}
<Move3D className="h-4 w-4" /> >
<span>角度</span> <Move3D className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">角度编辑</TooltipContent>
</Tooltip>
{/* 扩展 */} {/* 扩展 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" variant="ghost"
onClick={() => handleAction('extend')} size="icon"
title="图片扩展" className="h-8 w-8 rounded-full hover:bg-gray-100"
> onClick={() => handleAction('extend')}
<Expand className="h-4 w-4" /> >
<span>扩展</span> <Expand className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">图片扩展</TooltipContent>
</Tooltip>
{/* 尺寸调整 */} {/* 尺寸调整 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" variant="ghost"
onClick={() => handleAction('resize')} size="icon"
title="尺寸调整" className="h-8 w-8 rounded-full hover:bg-gray-100"
> onClick={() => handleAction('resize')}
<Maximize2 className="h-4 w-4" /> >
<span>调整</span> <Maximize2 className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">尺寸调整</TooltipContent>
</Tooltip>
{/* 图片标注 */} {/* 图片标注 */}
<Button <Tooltip>
variant="ghost" <TooltipTrigger asChild>
size="sm" <Button
className={`h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100 ${data.hasAnnotations ? 'text-primary' : ''}`} variant="ghost"
onClick={() => handleAction('annotate')} size="icon"
title="标注图片重点区域" className={cn("h-8 w-8 rounded-full hover:bg-gray-100", data.hasAnnotations && "text-primary")}
> onClick={() => handleAction('annotate')}
<Pencil className="h-4 w-4" /> >
<span>标注</span> <Pencil className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">标注重点区域</TooltipContent>
</Tooltip>
{/* 更多操作 */} {/* 下载 */}
<DropdownMenu> <Tooltip>
<DropdownMenuTrigger asChild> <TooltipTrigger asChild>
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="icon"
className="h-9 px-2 rounded-full hover:bg-gray-100" className="h-8 w-8 rounded-full hover:bg-gray-100"
title="更多" onClick={handleDownload}
> >
<MoreVertical className="h-4 w-4" /> <Download className="h-4 w-4" />
</Button> </Button>
</DropdownMenuTrigger> </TooltipTrigger>
<DropdownMenuContent align="end"> <TooltipContent side="bottom" className="text-xs">下载图片</TooltipContent>
<DropdownMenuItem onClick={handleDownload}> </Tooltip>
<Download className="h-4 w-4 mr-2" />
下载图片 {/* 删除 */}
</DropdownMenuItem> <Tooltip>
<DropdownMenuSeparator /> <TooltipTrigger asChild>
<DropdownMenuItem <Button
onClick={() => deleteNode(node.id)} variant="ghost"
className="text-destructive focus:text-destructive" size="icon"
> className="h-8 w-8 rounded-full hover:bg-red-50 text-red-500 hover:text-red-600"
<Trash2 className="h-4 w-4 mr-2" /> onClick={() => deleteNode(node.id)}
删除 >
</DropdownMenuItem> <Trash2 className="h-4 w-4" />
</DropdownMenuContent> </Button>
</DropdownMenu> </TooltipTrigger>
</div>, <TooltipContent side="bottom" className="text-xs">删除</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>,
document.body document.body
)} )}