feat: 图片工具栏改为纯图标模式,悬停显示功能名称
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

- 移除工具栏按钮的文字标签,只显示图标
- 使用 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"
<div className="h-5 w-px bg-gray-200 mx-1" /> size="icon"
className="h-8 w-8 rounded-full hover:bg-blue-50 text-blue-600 hover:text-blue-700"
{/* 放大/高清 */} onClick={() => {
<Button addPendingChatAttachment({
variant="ghost" url: data.src!,
size="sm" name: data.prompt || '画布图片',
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" contentType: 'image/jpeg',
onClick={() => handleAction('enhance')} });
title="高清放大" toast.success('已添加到对话框');
> }}
<span className="text-[10px] font-medium text-gray-500 border border-gray-300 rounded px-1">HD</span> >
<span>放大</span> <MessageSquarePlus className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
{/* 移除背景/抠图 */} <TooltipContent side="bottom" className="text-xs">添加到对话</TooltipContent>
<Button </Tooltip>
variant="ghost"
size="sm" {/* 分隔线 */}
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" <div className="h-5 w-px bg-gray-200 mx-0.5" />
onClick={() => handleAction('rmbg')}
title="移除背景" {/* 放大/高清 */}
> <Tooltip>
<Scissors className="h-4 w-4" /> <TooltipTrigger asChild>
<span>移除背景</span> <Button
</Button> variant="ghost"
size="icon"
{/* 场景融合 */} className="h-8 w-8 rounded-full hover:bg-gray-100"
<Button onClick={() => handleAction('enhance')}
variant="ghost" >
size="sm" <span className="text-[10px] font-medium text-gray-500 border border-gray-300 rounded px-1">HD</span>
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" </Button>
onClick={() => handleAction('scene-fusion')} </TooltipTrigger>
title="场景融合" <TooltipContent side="bottom" className="text-xs">高清放大</TooltipContent>
> </Tooltip>
<Layers className="h-4 w-4" />
<span>场景</span> {/* 移除背景/抠图 */}
</Button> <Tooltip>
<TooltipTrigger asChild>
{/* 角度编辑 */} <Button
<Button variant="ghost"
variant="ghost" size="icon"
size="sm" className="h-8 w-8 rounded-full hover:bg-gray-100"
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" onClick={() => handleAction('rmbg')}
onClick={() => handleAction('angle')} >
title="角度编辑" <Scissors className="h-4 w-4" />
> </Button>
<Move3D className="h-4 w-4" /> </TooltipTrigger>
<span>角度</span> <TooltipContent side="bottom" className="text-xs">移除背景</TooltipContent>
</Button> </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('scene-fusion')}
<Expand className="h-4 w-4" /> >
<span>扩展</span> <Layers className="h-4 w-4" />
</Button> </Button>
</TooltipTrigger>
{/* 尺寸调整 */} <TooltipContent side="bottom" className="text-xs">场景融合</TooltipContent>
<Button </Tooltip>
variant="ghost"
size="sm" {/* 角度编辑 */}
className="h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100" <Tooltip>
onClick={() => handleAction('resize')} <TooltipTrigger asChild>
title="尺寸调整" <Button
> variant="ghost"
<Maximize2 className="h-4 w-4" /> size="icon"
<span>调整</span> className="h-8 w-8 rounded-full hover:bg-gray-100"
</Button> onClick={() => handleAction('angle')}
>
{/* 图片标注 */} <Move3D className="h-4 w-4" />
<Button </Button>
variant="ghost" </TooltipTrigger>
size="sm" <TooltipContent side="bottom" className="text-xs">角度编辑</TooltipContent>
className={`h-9 px-3 text-xs gap-1.5 rounded-full hover:bg-gray-100 ${data.hasAnnotations ? 'text-primary' : ''}`} </Tooltip>
onClick={() => handleAction('annotate')}
title="标注图片重点区域" {/* 扩展 */}
> <Tooltip>
<Pencil className="h-4 w-4" /> <TooltipTrigger asChild>
<span>标注</span> <Button
</Button> variant="ghost"
size="icon"
{/* 更多操作 */} className="h-8 w-8 rounded-full hover:bg-gray-100"
<DropdownMenu> onClick={() => handleAction('extend')}
<DropdownMenuTrigger asChild> >
<Button <Expand className="h-4 w-4" />
variant="ghost" </Button>
size="sm" </TooltipTrigger>
className="h-9 px-2 rounded-full hover:bg-gray-100" <TooltipContent side="bottom" className="text-xs">图片扩展</TooltipContent>
title="更多" </Tooltip>
>
<MoreVertical className="h-4 w-4" /> {/* 尺寸调整 */}
</Button> <Tooltip>
</DropdownMenuTrigger> <TooltipTrigger asChild>
<DropdownMenuContent align="end"> <Button
<DropdownMenuItem onClick={handleDownload}> variant="ghost"
<Download className="h-4 w-4 mr-2" /> size="icon"
下载图片 className="h-8 w-8 rounded-full hover:bg-gray-100"
</DropdownMenuItem> onClick={() => handleAction('resize')}
<DropdownMenuSeparator /> >
<DropdownMenuItem <Maximize2 className="h-4 w-4" />
onClick={() => deleteNode(node.id)} </Button>
className="text-destructive focus:text-destructive" </TooltipTrigger>
> <TooltipContent side="bottom" className="text-xs">尺寸调整</TooltipContent>
<Trash2 className="h-4 w-4 mr-2" /> </Tooltip>
删除
</DropdownMenuItem> {/* 图片标注 */}
</DropdownMenuContent> <Tooltip>
</DropdownMenu> <TooltipTrigger asChild>
</div>, <Button
variant="ghost"
size="icon"
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" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">标注重点区域</TooltipContent>
</Tooltip>
{/* 下载 */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 rounded-full hover:bg-gray-100"
onClick={handleDownload}
>
<Download className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">下载图片</TooltipContent>
</Tooltip>
{/* 删除 */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-8 w-8 rounded-full hover:bg-red-50 text-red-500 hover:text-red-600"
onClick={() => deleteNode(node.id)}
>
<Trash2 className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">删除</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>,
document.body document.body
)} )}