diff --git a/src/renderer/src/pages/home/Markdown/PlantUML.tsx b/src/renderer/src/pages/home/Markdown/PlantUML.tsx index 1bf97a11..10bf50ba 100644 --- a/src/renderer/src/pages/home/Markdown/PlantUML.tsx +++ b/src/renderer/src/pages/home/Markdown/PlantUML.tsx @@ -86,6 +86,7 @@ type PlantUMLServerImageProps = { format: 'png' | 'svg' diagram: string onClick?: React.MouseEventHandler + className?: string } function getPlantUMLImageUrl(format: 'png' | 'svg', diagram: string, isDark?: boolean) { @@ -96,13 +97,13 @@ function getPlantUMLImageUrl(format: 'png' | 'svg', diagram: string, isDark?: bo return `${PlantUMLServer}/${format}/${encodedDiagram}` } -const PlantUMLServerImage: React.FC = ({ format, diagram, onClick }) => { +const PlantUMLServerImage: React.FC = ({ format, diagram, onClick, className }) => { const [loading, setLoading] = useState(true) const { theme } = useTheme() const isDark = theme === 'dark' const url = getPlantUMLImageUrl(format, diagram, isDark) return ( - + = ({ resolve, diagram png: false, svg: false }) - + const [scale, setScale] = useState(1) const [activeTab, setActiveTab] = useState('preview') const { t } = useTranslation() @@ -151,6 +152,51 @@ const PlantUMLPopupCantaier: React.FC = ({ resolve, diagram const onClose = () => { resolve({}) } + + const handleZoom = (delta: number) => { + const newScale = Math.max(0.1, Math.min(3, scale + delta)) + setScale(newScale) + + const container = document.querySelector('.plantuml-image-container') + if (container) { + const img = container.querySelector('img') + if (img) { + img.style.transformOrigin = 'top left' + img.style.transform = `scale(${newScale})` + } + } + } + + const handleCopyImage = async () => { + try { + const imageElement = document.querySelector('.plantuml-image-container img') + if (!imageElement) return + + const canvas = document.createElement('canvas') + const ctx = canvas.getContext('2d') + const img = imageElement as HTMLImageElement + + if (!img.complete) { + await new Promise((resolve) => { + img.onload = resolve + }) + } + + canvas.width = img.naturalWidth + canvas.height = img.naturalHeight + + if (ctx) { + ctx.drawImage(img, 0, 0) + const blob = await new Promise((resolve) => canvas.toBlob((b) => resolve(b!), 'image/png')) + await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]) + window.message.success(t('message.copy.success')) + } + } catch (error) { + console.error('Copy failed:', error) + window.message.error(t('message.copy.failed')) + } + } + const handleDownload = (format: 'svg' | 'png') => { const timestamp = Date.now() const url = `${PlantUMLServer}/${format}/${encodedDiagram}` @@ -188,6 +234,9 @@ const PlantUMLPopupCantaier: React.FC = ({ resolve, diagram )} {activeTab === 'preview' && ( <> + + + @@ -205,7 +254,7 @@ const PlantUMLPopupCantaier: React.FC = ({ resolve, diagram { key: 'preview', label: t('plantuml.tabs.preview'), - children: + children: }, { key: 'source', @@ -268,6 +317,7 @@ const StyledPlantUML = styled.div` min-height: 100px; background: var(--color-code-background); cursor: pointer; + transition: transform 0.2s ease; } ` async function downloadUrl(url: string, filename: string) {