diff --git a/src/App.tsx b/src/App.tsx index 143c1ab..f95a8a9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -24,6 +24,8 @@ function AppContent() { const { showPromptPanel, setShowPromptPanel, setShowHistory } = useAppStore(); const [hoveredImage, setHoveredImage] = useState<{url: string, title: string, width?: number, height?: number} | null>(null); + const [previewPosition, setPreviewPosition] = useState<{x: number, y: number} | null>(null); + const [isPreviewVisible, setIsPreviewVisible] = useState(false); // 在挂载时初始化IndexedDB并清理base64数据 useEffect(() => { @@ -73,6 +75,19 @@ function AppContent() { return () => clearInterval(interval); }, []); + // 控制预览窗口的显示和隐藏动画 + useEffect(() => { + if (hoveredImage) { + // 延迟一小段时间后设置为可见,以触发动画 + const timer = setTimeout(() => { + setIsPreviewVisible(true); + }, 10); + return () => clearTimeout(timer); + } else { + setIsPreviewVisible(false); + } + }, [hoveredImage]); + return (
@@ -92,7 +107,7 @@ function AppContent() {
- +
@@ -102,7 +117,14 @@ function AppContent() {
-
+
{hoveredImage.title}
diff --git a/src/components/HistoryPanel.tsx b/src/components/HistoryPanel.tsx index 8e460a4..63c0caf 100644 --- a/src/components/HistoryPanel.tsx +++ b/src/components/HistoryPanel.tsx @@ -9,7 +9,10 @@ import { useIndexedDBListener } from '../hooks/useIndexedDBListener'; import { DayPicker } from 'react-day-picker'; import zhCN from 'react-day-picker/dist/locale/zh-CN'; -export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, title: string, width?: number, height?: number} | null) => void }> = ({ setHoveredImage }) => { +export const HistoryPanel: React.FC<{ + setHoveredImage: (image: {url: string, title: string, width?: number, height?: number} | null) => void, + setPreviewPosition?: (position: {x: number, y: number} | null) => void +}> = ({ setHoveredImage, setPreviewPosition }) => { const { currentProject, canvasImage, @@ -534,6 +537,10 @@ export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, tit width: img.width, height: img.height }); + // 传递鼠标位置信息给App组件 + if (setPreviewPosition) { + setPreviewPosition({ x: e.clientX, y: e.clientY }); + } }; img.onerror = (error) => { console.error('图像加载失败:', error); @@ -544,6 +551,10 @@ export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, tit width: 0, height: 0 }); + // 传递鼠标位置信息给App组件 + if (setPreviewPosition) { + setPreviewPosition({ x: e.clientX, y: e.clientY }); + } }; img.src = imageUrl; } @@ -553,6 +564,9 @@ export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, tit }} onMouseLeave={() => { setHoveredImage(null); + if (setPreviewPosition) { + setPreviewPosition(null); + } }} > {(() => { @@ -631,6 +645,10 @@ export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, tit width: img.width, height: img.height }); + // 传递鼠标位置信息给App组件 + if (setPreviewPosition) { + setPreviewPosition({ x: e.clientX, y: e.clientY }); + } }; img.onerror = (error) => { console.error('图像加载失败:', error); @@ -641,6 +659,10 @@ export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, tit width: 0, height: 0 }); + // 传递鼠标位置信息给App组件 + if (setPreviewPosition) { + setPreviewPosition({ x: e.clientX, y: e.clientY }); + } }; img.src = imageUrl; } @@ -650,6 +672,9 @@ export const HistoryPanel: React.FC<{ setHoveredImage: (image: {url: string, tit }} onMouseLeave={() => { setHoveredImage(null); + if (setPreviewPosition) { + setPreviewPosition(null); + } }} > {(() => { diff --git a/src/services/uploadService.ts b/src/services/uploadService.ts index 3e973cf..8e155fe 100644 --- a/src/services/uploadService.ts +++ b/src/services/uploadService.ts @@ -8,7 +8,7 @@ const UPLOAD_URL = import.meta.env.VITE_UPLOAD_API const uploadCache = new Map() // 缓存配置 -const MAX_CACHE_SIZE = 50 // 减少最大缓存条目数 +const MAX_CACHE_SIZE = 20 // 减少最大缓存条目数 const CACHE_EXPIRY_TIME = 15 * 60 * 1000 // 缓存过期时间15分钟 /**