From a163e7a2a0e9849ae517921246e71867e4a4cbca Mon Sep 17 00:00:00 2001
From: nanhaoluo <3075912108@qq.com>
Date: Sat, 24 Jan 2026 23:36:12 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20Mermaid=20?=
=?UTF-8?q?=E5=9B=BE=E8=A1=A8=E7=BC=A9=E6=94=BE=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 图表容器宽度占满,只留文章边距(margin: 20px -20px)
- 添加缩放控制按钮:放大、缩小、重置
- 支持 Ctrl+滚轮缩放
- 缩放范围:50%-300%,步进 25%
- 响应式适配:移动端自动调整边距和按钮大小
- 夜间模式适配缩放控制按钮样式
---
argontheme.js | 83 ++++++++++++++++++++-
style.css | 202 +++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 272 insertions(+), 13 deletions(-)
diff --git a/argontheme.js b/argontheme.js
index 54d46fb..8f00363 100644
--- a/argontheme.js
+++ b/argontheme.js
@@ -5147,7 +5147,7 @@ void 0;
// ---------- 样式增强 ----------
/**
- * 应用容器样式
+ * 应用容器样式并添加缩放控制
* @param {HTMLElement} container - 图表容器
*/
applyStyles(container) {
@@ -5161,9 +5161,88 @@ void 0;
// 确保 SVG 响应式
const svg = container.querySelector('svg');
if (svg) {
- svg.style.maxWidth = '100%';
+ svg.style.width = '100%';
svg.style.height = 'auto';
}
+
+ // 添加缩放功能
+ this.addZoomControls(container);
+ },
+
+ /**
+ * 添加缩放控制按钮
+ * @param {HTMLElement} container - 图表容器
+ */
+ addZoomControls(container) {
+ // 创建内部容器包裹 SVG
+ const svg = container.querySelector('svg');
+ if (!svg) return;
+
+ // 创建内部容器
+ const inner = document.createElement('div');
+ inner.className = 'mermaid-container-inner';
+
+ // 将 SVG 移到内部容器
+ container.appendChild(inner);
+ inner.appendChild(svg);
+
+ // 创建缩放控制
+ const controls = document.createElement('div');
+ controls.className = 'mermaid-zoom-controls';
+ controls.innerHTML = `
+
+ 100%
+
+
+ `;
+
+ container.appendChild(controls);
+
+ // 缩放状态
+ let scale = 1;
+ const minScale = 0.5;
+ const maxScale = 3;
+ const step = 0.25;
+
+ // 更新缩放显示
+ const updateZoom = () => {
+ inner.style.transform = `scale(${scale})`;
+ controls.querySelector('.mermaid-zoom-level').textContent = Math.round(scale * 100) + '%';
+ };
+
+ // 绑定按钮事件
+ controls.addEventListener('click', (e) => {
+ const btn = e.target.closest('.mermaid-zoom-btn');
+ if (!btn) return;
+
+ const action = btn.dataset.action;
+
+ if (action === 'zoom-in' && scale < maxScale) {
+ scale = Math.min(scale + step, maxScale);
+ updateZoom();
+ } else if (action === 'zoom-out' && scale > minScale) {
+ scale = Math.max(scale - step, minScale);
+ updateZoom();
+ } else if (action === 'zoom-reset') {
+ scale = 1;
+ updateZoom();
+ }
+ });
+
+ // 鼠标滚轮缩放(按住 Ctrl)
+ container.addEventListener('wheel', (e) => {
+ if (e.ctrlKey || e.metaKey) {
+ e.preventDefault();
+
+ const delta = e.deltaY > 0 ? -step : step;
+ const newScale = Math.max(minScale, Math.min(maxScale, scale + delta));
+
+ if (newScale !== scale) {
+ scale = newScale;
+ updateZoom();
+ }
+ }
+ }, { passive: false });
},
// ---------- 主题切换监听 ----------
diff --git a/style.css b/style.css
index dbd7c2d..4c4b166 100644
--- a/style.css
+++ b/style.css
@@ -913,21 +913,81 @@ article .wp-block-separator {
background: var(--color-foreground);
border-radius: 8px;
padding: 20px;
- margin: 20px 0;
+ margin: 20px -20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- overflow-x: auto;
- max-width: 100%;
+ overflow: hidden;
+ position: relative;
opacity: 0;
animation: mermaidFadeIn 0.3s ease-in-out forwards;
}
+.mermaid-container-inner {
+ overflow: auto;
+ transform-origin: top left;
+ transition: transform 0.3s ease;
+}
+
.mermaid-container svg {
width: 100% !important;
height: auto !important;
- max-width: 100%;
display: block;
}
+/* 缩放控制按钮 */
+.mermaid-zoom-controls {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ display: flex;
+ gap: 5px;
+ z-index: 10;
+ background: rgba(255, 255, 255, 0.9);
+ border-radius: 6px;
+ padding: 5px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+}
+
+html.darkmode .mermaid-zoom-controls {
+ background: rgba(30, 30, 30, 0.9);
+}
+
+.mermaid-zoom-btn {
+ width: 32px;
+ height: 32px;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ color: #5e72e4;
+ transition: all 0.2s;
+}
+
+.mermaid-zoom-btn:hover {
+ background: rgba(94, 114, 228, 0.1);
+}
+
+.mermaid-zoom-btn:active {
+ transform: scale(0.95);
+}
+
+.mermaid-zoom-level {
+ display: flex;
+ align-items: center;
+ padding: 0 8px;
+ font-size: 13px;
+ color: #666;
+ min-width: 50px;
+ justify-content: center;
+}
+
+html.darkmode .mermaid-zoom-level {
+ color: #aaa;
+}
+
/* Mermaid 淡入动画 */
@keyframes mermaidFadeIn {
from {
@@ -942,7 +1002,42 @@ article .wp-block-separator {
/* 文章卡片内的 Mermaid 图表 */
article.card .mermaid-container {
- margin: 20px 0;
+ margin: 20px -20px;
+}
+
+/* 响应式调整 */
+@media screen and (max-width: 768px) {
+ .mermaid-container {
+ margin: 15px -15px;
+ padding: 15px;
+ }
+
+ article.card .mermaid-container {
+ margin: 15px -15px;
+ }
+}
+
+@media screen and (max-width: 480px) {
+ .mermaid-container {
+ margin: 10px -10px;
+ padding: 10px;
+ }
+
+ article.card .mermaid-container {
+ margin: 10px -10px;
+ }
+
+ .mermaid-zoom-controls {
+ top: 5px;
+ right: 5px;
+ padding: 3px;
+ }
+
+ .mermaid-zoom-btn {
+ width: 28px;
+ height: 28px;
+ font-size: 16px;
+ }
}
/* Mermaid 错误提示样式 */
@@ -16629,24 +16724,85 @@ html.darkmode .mermaid-error-container .error-code code {
padding: 20px;
margin: 20px 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- overflow-x: auto;
- max-width: 100%;
+ overflow: hidden;
+ position: relative;
+ margin: 20px -20px;
transition: opacity 0.3s ease-in;
}
+.mermaid-container-inner {
+ overflow: auto;
+ transform-origin: top left;
+ transition: transform 0.3s ease;
+}
+
.mermaid-container svg {
width: 100% !important;
height: auto !important;
- max-width: 100%;
display: block;
}
+/* 缩放控制按钮 */
+.mermaid-zoom-controls {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ display: flex;
+ gap: 5px;
+ z-index: 10;
+ background: rgba(255, 255, 255, 0.9);
+ border-radius: 6px;
+ padding: 5px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+}
+
+html.darkmode .mermaid-zoom-controls {
+ background: rgba(30, 30, 30, 0.9);
+}
+
+.mermaid-zoom-btn {
+ width: 32px;
+ height: 32px;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ color: #5e72e4;
+ transition: all 0.2s;
+}
+
+.mermaid-zoom-btn:hover {
+ background: rgba(94, 114, 228, 0.1);
+}
+
+.mermaid-zoom-btn:active {
+ transform: scale(0.95);
+}
+
+.mermaid-zoom-level {
+ display: flex;
+ align-items: center;
+ padding: 0 8px;
+ font-size: 13px;
+ color: #666;
+ min-width: 50px;
+ justify-content: center;
+}
+
+html.darkmode .mermaid-zoom-level {
+ color: #aaa;
+}
+
/* ---------- 卡片内的 Mermaid 图表 ---------- */
.card .mermaid-container,
.post-card .mermaid-container,
.comment-content .mermaid-container {
padding: 15px;
- margin: 15px 0;
+ margin: 15px -15px;
}
/* ---------- 夜间模式适配 ---------- */
@@ -16659,15 +16815,39 @@ html.darkmode .mermaid-container {
@media screen and (max-width: 768px) {
.mermaid-container {
padding: 15px;
- margin: 15px 0;
+ margin: 15px -15px;
border-radius: calc(var(--card-radius) * 0.8);
}
+
+ .card .mermaid-container,
+ .post-card .mermaid-container,
+ .comment-content .mermaid-container {
+ margin: 15px -15px;
+ }
}
@media screen and (max-width: 480px) {
.mermaid-container {
padding: 10px;
- margin: 10px 0;
+ margin: 10px -10px;
+ }
+
+ .card .mermaid-container,
+ .post-card .mermaid-container,
+ .comment-content .mermaid-container {
+ margin: 10px -10px;
+ }
+
+ .mermaid-zoom-controls {
+ top: 5px;
+ right: 5px;
+ padding: 3px;
+ }
+
+ .mermaid-zoom-btn {
+ width: 28px;
+ height: 28px;
+ font-size: 16px;
}
}