feat: 支持 mermaid 点击按钮放大缩小以及鼠标滑轮放大缩小
This commit is contained in:
parent
a0413158c8
commit
ce973ce3a0
@ -185,6 +185,7 @@ export class WindowService {
|
|||||||
private loadMainWindowContent(mainWindow: BrowserWindow) {
|
private loadMainWindowContent(mainWindow: BrowserWindow) {
|
||||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
||||||
|
mainWindow.webContents.openDevTools()
|
||||||
} else {
|
} else {
|
||||||
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,4 +37,32 @@ export const useMermaid = () => {
|
|||||||
|
|
||||||
setTimeout(renderMermaid, 100)
|
setTimeout(renderMermaid, 100)
|
||||||
}, [generating])
|
}, [generating])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleWheel = (e: WheelEvent) => {
|
||||||
|
if (e.ctrlKey || e.metaKey) {
|
||||||
|
e.preventDefault()
|
||||||
|
const mermaidElement = (e.target as HTMLElement).closest('.mermaid')
|
||||||
|
if (!mermaidElement) return
|
||||||
|
|
||||||
|
const svg = mermaidElement.querySelector('svg')
|
||||||
|
if (!svg) return
|
||||||
|
|
||||||
|
const currentScale = parseFloat(svg.style.transform?.match(/scale\((.*?)\)/)?.[1] || '1')
|
||||||
|
const delta = e.deltaY < 0 ? 0.1 : -0.1
|
||||||
|
const newScale = Math.max(0.1, Math.min(3, currentScale + delta))
|
||||||
|
|
||||||
|
const container = svg.parentElement
|
||||||
|
if (container) {
|
||||||
|
container.style.overflow = 'auto'
|
||||||
|
container.style.position = 'relative'
|
||||||
|
svg.style.transformOrigin = 'top left'
|
||||||
|
svg.style.transform = `scale(${newScale})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('wheel', handleWheel, { passive: false })
|
||||||
|
return () => document.removeEventListener('wheel', handleWheel)
|
||||||
|
}, [])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -217,6 +217,10 @@
|
|||||||
"png": "Download PNG",
|
"png": "Download PNG",
|
||||||
"svg": "Download SVG"
|
"svg": "Download SVG"
|
||||||
},
|
},
|
||||||
|
"resize": {
|
||||||
|
"zoom-in": "Zoom In",
|
||||||
|
"zoom-out": "Zoom Out"
|
||||||
|
},
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"source": "Source"
|
"source": "Source"
|
||||||
|
|||||||
@ -217,6 +217,10 @@
|
|||||||
"png": "PNGをダウンロード",
|
"png": "PNGをダウンロード",
|
||||||
"svg": "SVGをダウンロード"
|
"svg": "SVGをダウンロード"
|
||||||
},
|
},
|
||||||
|
"resize": {
|
||||||
|
"zoom-in": "拡大する",
|
||||||
|
"zoom-out": "ズームアウト"
|
||||||
|
},
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"preview": "プレビュー",
|
"preview": "プレビュー",
|
||||||
"source": "ソース"
|
"source": "ソース"
|
||||||
|
|||||||
@ -217,6 +217,10 @@
|
|||||||
"png": "Скачать PNG",
|
"png": "Скачать PNG",
|
||||||
"svg": "Скачать SVG"
|
"svg": "Скачать SVG"
|
||||||
},
|
},
|
||||||
|
"resize": {
|
||||||
|
"zoom-in": "Yвеличить",
|
||||||
|
"zoom-out": "Yменьшить масштаб"
|
||||||
|
},
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"preview": "Предпросмотр",
|
"preview": "Предпросмотр",
|
||||||
"source": "Исходный код"
|
"source": "Исходный код"
|
||||||
|
|||||||
@ -218,6 +218,10 @@
|
|||||||
"png": "下载 PNG",
|
"png": "下载 PNG",
|
||||||
"svg": "下载 SVG"
|
"svg": "下载 SVG"
|
||||||
},
|
},
|
||||||
|
"resize": {
|
||||||
|
"zoom-in": "放大",
|
||||||
|
"zoom-out": "缩小"
|
||||||
|
},
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"preview": "预览",
|
"preview": "预览",
|
||||||
"source": "源码"
|
"source": "源码"
|
||||||
|
|||||||
@ -217,6 +217,10 @@
|
|||||||
"png": "下載 PNG",
|
"png": "下載 PNG",
|
||||||
"svg": "下載 SVG"
|
"svg": "下載 SVG"
|
||||||
},
|
},
|
||||||
|
"resize": {
|
||||||
|
"zoom-in": "放大",
|
||||||
|
"zoom-out": "縮小"
|
||||||
|
},
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"preview": "預覽",
|
"preview": "預覽",
|
||||||
"source": "原始碼"
|
"source": "原始碼"
|
||||||
|
|||||||
@ -18,6 +18,7 @@ const PopupContainer: React.FC<Props> = ({ resolve, chart }) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const mermaidId = `mermaid-popup-${Date.now()}`
|
const mermaidId = `mermaid-popup-${Date.now()}`
|
||||||
const [activeTab, setActiveTab] = useState('preview')
|
const [activeTab, setActiveTab] = useState('preview')
|
||||||
|
const [scale, setScale] = useState(1)
|
||||||
|
|
||||||
const onOk = () => {
|
const onOk = () => {
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
@ -31,6 +32,25 @@ const PopupContainer: React.FC<Props> = ({ resolve, chart }) => {
|
|||||||
resolve({})
|
resolve({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleZoom = (delta: number) => {
|
||||||
|
const newScale = Math.max(0.1, Math.min(3, scale + delta))
|
||||||
|
setScale(newScale)
|
||||||
|
|
||||||
|
const element = document.getElementById(mermaidId)
|
||||||
|
if (!element) return
|
||||||
|
|
||||||
|
const svg = element.querySelector('svg')
|
||||||
|
if (!svg) return
|
||||||
|
|
||||||
|
const container = svg.parentElement
|
||||||
|
if (container) {
|
||||||
|
container.style.overflow = 'auto'
|
||||||
|
container.style.position = 'relative'
|
||||||
|
svg.style.transformOrigin = 'top left'
|
||||||
|
svg.style.transform = `scale(${newScale})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleDownload = async (format: 'svg' | 'png') => {
|
const handleDownload = async (format: 'svg' | 'png') => {
|
||||||
try {
|
try {
|
||||||
const element = document.getElementById(mermaidId)
|
const element = document.getElementById(mermaidId)
|
||||||
@ -110,6 +130,8 @@ const PopupContainer: React.FC<Props> = ({ resolve, chart }) => {
|
|||||||
{activeTab === 'source' && <Button onClick={() => handleCopy()}>{t('common.copy')}</Button>}
|
{activeTab === 'source' && <Button onClick={() => handleCopy()}>{t('common.copy')}</Button>}
|
||||||
{activeTab === 'preview' && (
|
{activeTab === 'preview' && (
|
||||||
<>
|
<>
|
||||||
|
<Button onClick={() => handleZoom(0.1)}>{t('mermaid.resize.zoom-in')}</Button>
|
||||||
|
<Button onClick={() => handleZoom(-0.1)}>{t('mermaid.resize.zoom-out')}</Button>
|
||||||
<Button onClick={() => handleDownload('svg')}>{t('mermaid.download.svg')}</Button>
|
<Button onClick={() => handleDownload('svg')}>{t('mermaid.download.svg')}</Button>
|
||||||
<Button onClick={() => handleDownload('png')}>{t('mermaid.download.png')}</Button>
|
<Button onClick={() => handleDownload('png')}>{t('mermaid.download.png')}</Button>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user