feat(canvas): 添加画布图片信息显示功能

- 在画布项目状态中添加 showImageInfo 属性
- 实现图片信息栏组件显示图片尺寸和文件大小
- 添加画布工具栏开关控制图片信息显示
- 将图片信息状态集成到项目历史记录和持久化
- 更新画布节点组件支持图片信息显示功能
This commit is contained in:
HouYunFei
2026-05-25 15:51:14 +08:00
parent 2934b1d0bc
commit 030541b99d
6 changed files with 54 additions and 38 deletions
@@ -5,6 +5,7 @@ import type { ReactNode } from "react";
import { ChevronRight, Image as ImageIcon, RefreshCw, Star, Video } from "lucide-react";
import { canvasThemes } from "@/lib/canvas-theme";
import { formatBytes } from "@/lib/image-utils";
import { useThemeStore } from "@/stores/use-theme-store";
import { CanvasNodeType, type CanvasNodeData, type Position } from "../types";
@@ -21,6 +22,7 @@ type CanvasNodeProps = {
isConnecting: boolean;
editRequestNonce?: number;
showPanel: boolean;
showImageInfo: boolean;
renderPanel?: (node: CanvasNodeData) => ReactNode;
renderNodeContent?: (node: CanvasNodeData) => ReactNode;
batchCount?: number;
@@ -71,6 +73,7 @@ export const CanvasNode = React.memo(function CanvasNode({
isConnecting,
editRequestNonce = 0,
showPanel,
showImageInfo,
renderPanel,
renderNodeContent,
batchCount = 0,
@@ -296,6 +299,8 @@ export const CanvasNode = React.memo(function CanvasNode({
/>
</div>
{showImageInfo && hasImageContent ? <ImageInfoBar node={data} /> : null}
{!hasImageContent && !hasVideoContent ? <div className="pointer-events-none absolute inset-x-0 bottom-0 h-12" style={{ background: `linear-gradient(to top, ${theme.canvas.background}66, transparent)` }} /> : null}
<ResizeHandle corner="top-left" onMouseDown={handleResizeMouseDown} />
@@ -537,6 +542,20 @@ function ImageContent({
);
}
function ImageInfoBar({ node }: { node: CanvasNodeData }) {
const width = Math.round(node.metadata?.naturalWidth || node.width);
const height = Math.round(node.metadata?.naturalHeight || node.height);
const size = formatBytes(node.metadata?.bytes || 0);
return (
<div className="pointer-events-none absolute bottom-3 right-3 z-40 max-w-[calc(100%-24px)]">
<span className="max-w-full truncate rounded-md bg-black/55 px-2 py-1 text-[11px] font-medium leading-none text-white backdrop-blur-sm">
{width} x {height}
{size ? ` · ${size}` : ""}
</span>
</div>
);
}
function BatchFrame({ batchCount, batchExpanded, batchOpening, batchRecovering, onToggleBatch, children }: { batchCount: number; batchExpanded: boolean; batchOpening: boolean; batchRecovering: boolean; onToggleBatch?: () => void; children: ReactNode }) {
const theme = canvasThemes[useThemeStore((state) => state.theme)];
const isBatchRoot = batchCount > 1;