You've already forked Nano-Banana-AI-Image-Editor
优化 整体UI调整
This commit is contained in:
@@ -20,7 +20,9 @@ export const ImageCanvas: React.FC = () => {
|
||||
selectedTool,
|
||||
isGenerating,
|
||||
brushSize,
|
||||
setBrushSize
|
||||
setBrushSize,
|
||||
showHistory,
|
||||
showPromptPanel
|
||||
} = useAppStore();
|
||||
|
||||
const stageRef = useRef<any>(null);
|
||||
@@ -80,6 +82,22 @@ export const ImageCanvas: React.FC = () => {
|
||||
return () => window.removeEventListener('resize', updateSize);
|
||||
}, []);
|
||||
|
||||
// 监听面板状态变化以调整画布大小
|
||||
useEffect(() => {
|
||||
// 使用 setTimeout 确保 DOM 已更新
|
||||
const timer = setTimeout(() => {
|
||||
const container = document.getElementById('canvas-container');
|
||||
if (container) {
|
||||
setStageSize({
|
||||
width: container.offsetWidth,
|
||||
height: container.offsetHeight
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [showPromptPanel, showHistory]);
|
||||
|
||||
// 处理鼠标滚轮缩放
|
||||
useEffect(() => {
|
||||
const container = document.getElementById('canvas-container');
|
||||
@@ -188,69 +206,7 @@ export const ImageCanvas: React.FC = () => {
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
{/* 工具栏 */}
|
||||
<div className="p-2 border-b border-gray-200 bg-white">
|
||||
<div className="flex items-center justify-between">
|
||||
{/* 左侧 - 缩放控制 */}
|
||||
<div className="flex items-center space-x-1">
|
||||
<Button variant="outline" size="sm" onClick={() => handleZoom(-0.1)} className="h-8 w-8 p-0">
|
||||
<ZoomOut className="h-4 w-4" />
|
||||
</Button>
|
||||
<span className="text-xs text-gray-400 min-w-[40px] text-center">
|
||||
{Math.round(canvasZoom * 100)}%
|
||||
</span>
|
||||
<Button variant="outline" size="sm" onClick={() => handleZoom(0.1)} className="h-8 w-8 p-0">
|
||||
<ZoomIn className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="outline" size="sm" onClick={handleReset} className="h-8 w-8 p-0">
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 右侧 - 工具和操作 */}
|
||||
<div className="flex items-center space-x-1">
|
||||
{selectedTool === 'mask' && (
|
||||
<>
|
||||
<div className="flex items-center space-x-1 mr-1">
|
||||
<span className="text-xs text-gray-400">画笔:</span>
|
||||
<input
|
||||
type="range"
|
||||
min="5"
|
||||
max="50"
|
||||
value={brushSize}
|
||||
onChange={(e) => setBrushSize(parseInt(e.target.value))}
|
||||
className="w-12 h-2 bg-gray-800 rounded-lg appearance-none cursor-pointer slider"
|
||||
/>
|
||||
<span className="text-xs text-gray-400 w-6">{brushSize}</span>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={clearBrushStrokes}
|
||||
disabled={brushStrokes.length === 0}
|
||||
className="h-8 w-8 p-0"
|
||||
>
|
||||
<Eraser className="h-4 w-4" />
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setShowMasks(!showMasks)}
|
||||
className={cn(showMasks && 'bg-yellow-400/10 border-yellow-400/50', 'h-8 w-8 p-0')}
|
||||
>
|
||||
{showMasks ? <Eye className="h-4 w-4" /> : <EyeOff className="h-4 w-4" />}
|
||||
</Button>
|
||||
|
||||
{canvasImage && (
|
||||
<Button variant="secondary" size="sm" onClick={handleDownload} className="h-8 px-2">
|
||||
<Download className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 画布区域 */}
|
||||
<div
|
||||
@@ -276,7 +232,7 @@ export const ImageCanvas: React.FC = () => {
|
||||
|
||||
{isGenerating && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-gray-900/40 z-50 backdrop-blur-sm">
|
||||
<div className="text-center bg-white/90 rounded-xl p-6 shadow-lg">
|
||||
<div className="text-center bg-white/90 rounded-xl p-6 shadow-2xl backdrop-blur-sm border border-gray-200/50">
|
||||
<div className="animate-spin rounded-full h-10 w-10 border-2 border-yellow-400 border-t-transparent mx-auto mb-3" />
|
||||
<p className="text-gray-700 text-sm font-medium">正在创建图像...</p>
|
||||
</div>
|
||||
@@ -349,6 +305,48 @@ export const ImageCanvas: React.FC = () => {
|
||||
)}
|
||||
</Layer>
|
||||
</Stage>
|
||||
|
||||
{/* 悬浮操作按钮 */}
|
||||
{image && !isGenerating && (
|
||||
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 bg-white/80 backdrop-blur-sm rounded-full shadow-lg border border-gray-200 px-3 py-2 flex items-center space-x-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleZoom(-0.1)}
|
||||
className="h-8 w-8 p-0 text-gray-600 hover:text-gray-900 hover:bg-gray-100"
|
||||
>
|
||||
<ZoomOut className="h-4 w-4" />
|
||||
</Button>
|
||||
<span className="text-xs text-gray-500 min-w-[40px] text-center">
|
||||
{Math.round(canvasZoom * 100)}%
|
||||
</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleZoom(0.1)}
|
||||
className="h-8 w-8 p-0 text-gray-600 hover:text-gray-900 hover:bg-gray-100"
|
||||
>
|
||||
<ZoomIn className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleReset}
|
||||
className="h-8 w-8 p-0 text-gray-600 hover:text-gray-900 hover:bg-gray-100"
|
||||
>
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
</Button>
|
||||
<div className="w-px h-6 bg-gray-200"></div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleDownload}
|
||||
className="h-8 w-8 p-0 text-gray-600 hover:text-gray-900 hover:bg-gray-100"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 状态栏 */}
|
||||
|
||||
Reference in New Issue
Block a user