From c50ff7979060c4cf2811528748b400cde96f906f Mon Sep 17 00:00:00 2001 From: wonder Date: Mon, 24 Aug 2026 03:07:42 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Mermaid=20=E5=9B=BE=E8=A1=A8=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E6=94=BE=E5=A4=A7=EF=BC=88lightbox=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/css/mermaid-zoom.css | 30 ++++++++++++++++++ docs/js/mermaid-zoom.js | 67 +++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 6 ++++ 3 files changed, 103 insertions(+) create mode 100644 docs/css/mermaid-zoom.css create mode 100644 docs/js/mermaid-zoom.js diff --git a/docs/css/mermaid-zoom.css b/docs/css/mermaid-zoom.css new file mode 100644 index 0000000..ffc0ba3 --- /dev/null +++ b/docs/css/mermaid-zoom.css @@ -0,0 +1,30 @@ +.mermaid-zoom-overlay { + position: fixed; + inset: 0; + z-index: 9999; + background: rgba(0, 0, 0, 0.75); + display: flex; + align-items: center; + justify-content: center; + cursor: zoom-out; + opacity: 0; + transition: opacity 0.2s ease; +} + +.mermaid-zoom-overlay.active { + opacity: 1; +} + +.mermaid-zoom-overlay svg { + max-width: 95vw; + max-height: 95vh; + background: #fff; + border-radius: 8px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); + padding: 1.5rem; +} + +/* 让 Mermaid 容器看起来可点击 */ +.mermaid { + cursor: zoom-in; +} diff --git a/docs/js/mermaid-zoom.js b/docs/js/mermaid-zoom.js new file mode 100644 index 0000000..7564c04 --- /dev/null +++ b/docs/js/mermaid-zoom.js @@ -0,0 +1,67 @@ +document.addEventListener('DOMContentLoaded', function () { + // 等待 Mermaid 渲染完成(Mermaid 在 DOMContentLoaded 之后异步渲染) + const observer = new MutationObserver(function () { + const svgs = document.querySelectorAll('.mermaid svg'); + if (svgs.length > 0) { + observer.disconnect(); + initMermaidZoom(); + } + }); + + observer.observe(document.body, { childList: true, subtree: true }); + + // 也尝试立即初始化(以防 Mermaid 已经渲染完) + setTimeout(initMermaidZoom, 1000); +}); + +function initMermaidZoom() { + // 避免重复绑定 + if (document.querySelector('.mermaid-zoom-overlay')) return; + + document.querySelectorAll('.mermaid').forEach(function (el) { + if (el.dataset.zoomBound) return; + el.dataset.zoomBound = 'true'; + + el.addEventListener('click', function () { + const svg = el.querySelector('svg'); + if (!svg) return; + + const clone = svg.cloneNode(true); + // 让克隆的 SVG 自适应放大 + clone.removeAttribute('width'); + clone.removeAttribute('height'); + clone.style.width = 'auto'; + clone.style.height = 'auto'; + clone.style.maxWidth = '95vw'; + clone.style.maxHeight = '95vh'; + + const overlay = document.createElement('div'); + overlay.className = 'mermaid-zoom-overlay'; + overlay.appendChild(clone); + + // 点击 overlay 关闭 + overlay.addEventListener('click', function (e) { + if (e.target === overlay || e.target.closest('svg')) { + overlay.classList.remove('active'); + setTimeout(function () { overlay.remove(); }, 200); + } + }); + + // ESC 关闭 + function onKey(e) { + if (e.key === 'Escape') { + overlay.classList.remove('active'); + setTimeout(function () { overlay.remove(); }, 200); + document.removeEventListener('keydown', onKey); + } + } + document.addEventListener('keydown', onKey); + + document.body.appendChild(overlay); + // 触发动画 + requestAnimationFrame(function () { + overlay.classList.add('active'); + }); + }); + }); +} diff --git a/mkdocs.yml b/mkdocs.yml index b7b925f..1287a5f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -78,6 +78,12 @@ markdown_extensions: custom_checkbox: true - pymdownx.tilde +extra_css: + - css/mermaid-zoom.css + +extra_javascript: + - js/mermaid-zoom.js + nav: - 首页: index.md - 项目: