feat: 实现 Mermaid 全屏模式
- 在工具栏添加全屏按钮(⛶ 图标) - 实现全屏模式进入和退出功能 - 全屏模式下保持缩放和拖拽功能可用 - 支持 ESC 键退出全屏 - 退出全屏时恢复图表原始状态(缩放级别和滚动位置) - 全屏模式下禁用页面滚动 - 添加全屏按钮激活状态样式 - 在清理函数中添加全屏事件监听器清理 - 全屏模式下工具栏始终可见,背景更明显 - 全屏容器占满整个视口,居中显示图表 需求:14.1, 14.2, 14.3, 14.4, 14.5
This commit is contained in:
@@ -54,10 +54,10 @@
|
|||||||
|
|
||||||
### 阶段 3: Mermaid 高级功能
|
### 阶段 3: Mermaid 高级功能
|
||||||
|
|
||||||
- [ ] 8. 实现 Mermaid 全屏模式
|
- [x] 8. 实现 Mermaid 全屏模式
|
||||||
- [ ] 8.1 添加全屏按钮 _需求:14.1_
|
- [x] 8.1 添加全屏按钮 _需求:14.1_
|
||||||
- [ ] 8.2 全屏模式功能保持 _需求:14.2, 14.3_
|
- [x] 8.2 全屏模式功能保持 _需求:14.2, 14.3_
|
||||||
- [ ] 8.3 全屏模式退出(ESC 键) _需求:14.4, 14.5_
|
- [x] 8.3 全屏模式退出(ESC 键) _需求:14.4, 14.5_
|
||||||
|
|
||||||
- [ ] 9. 实现 Mermaid 导出功能
|
- [ ] 9. 实现 Mermaid 导出功能
|
||||||
- [ ] 9.1 添加导出按钮和菜单 _需求:15.1_
|
- [ ] 9.1 添加导出按钮和菜单 _需求:15.1_
|
||||||
|
|||||||
119
argontheme.js
119
argontheme.js
@@ -2900,6 +2900,11 @@ function cleanupMermaidInstances() {
|
|||||||
const newToolbar = toolbar.cloneNode(true);
|
const newToolbar = toolbar.cloneNode(true);
|
||||||
toolbar.parentNode.replaceChild(newToolbar, toolbar);
|
toolbar.parentNode.replaceChild(newToolbar, toolbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理全屏模式
|
||||||
|
if (container._fullscreenCleanup) {
|
||||||
|
container._fullscreenCleanup();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ArgonDebug.log('Mermaid 实例已清理');
|
ArgonDebug.log('Mermaid 实例已清理');
|
||||||
@@ -5682,6 +5687,7 @@ void 0;
|
|||||||
inner.appendChild(svg);
|
inner.appendChild(svg);
|
||||||
|
|
||||||
// 创建缩放控制
|
// 创建缩放控制
|
||||||
|
// 需求 14.1: 添加全屏按钮
|
||||||
const controls = document.createElement('div');
|
const controls = document.createElement('div');
|
||||||
controls.className = 'mermaid-zoom-controls';
|
controls.className = 'mermaid-zoom-controls';
|
||||||
controls.innerHTML = `
|
controls.innerHTML = `
|
||||||
@@ -5689,6 +5695,7 @@ void 0;
|
|||||||
<span class="mermaid-zoom-level">100%</span>
|
<span class="mermaid-zoom-level">100%</span>
|
||||||
<button class="mermaid-zoom-btn" data-action="zoom-in" title="放大">+</button>
|
<button class="mermaid-zoom-btn" data-action="zoom-in" title="放大">+</button>
|
||||||
<button class="mermaid-zoom-btn" data-action="zoom-reset" title="重置">⟲</button>
|
<button class="mermaid-zoom-btn" data-action="zoom-reset" title="重置">⟲</button>
|
||||||
|
<button class="mermaid-zoom-btn" data-action="fullscreen" title="全屏">⛶</button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
container.appendChild(controls);
|
container.appendChild(controls);
|
||||||
@@ -5754,6 +5761,7 @@ void 0;
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 绑定按钮事件
|
// 绑定按钮事件
|
||||||
|
// 需求 14.1, 14.2, 14.3: 全屏按钮功能
|
||||||
controls.addEventListener('click', (e) => {
|
controls.addEventListener('click', (e) => {
|
||||||
const btn = e.target.closest('.mermaid-zoom-btn');
|
const btn = e.target.closest('.mermaid-zoom-btn');
|
||||||
if (!btn || btn.disabled) return; // 忽略禁用的按钮
|
if (!btn || btn.disabled) return; // 忽略禁用的按钮
|
||||||
@@ -5769,6 +5777,9 @@ void 0;
|
|||||||
} else if (action === 'zoom-reset') {
|
} else if (action === 'zoom-reset') {
|
||||||
scale = 1;
|
scale = 1;
|
||||||
updateZoom(true); // 重置使用平滑过渡
|
updateZoom(true); // 重置使用平滑过渡
|
||||||
|
} else if (action === 'fullscreen') {
|
||||||
|
// 需求 14.1: 点击全屏按钮
|
||||||
|
toggleFullscreen();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -5932,6 +5943,114 @@ void 0;
|
|||||||
}, 50);
|
}, 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ==========================================================================
|
||||||
|
// 需求 14: Mermaid 全屏模式
|
||||||
|
// ==========================================================================
|
||||||
|
|
||||||
|
// 全屏状态
|
||||||
|
let isFullscreen = false;
|
||||||
|
let savedScale = 1;
|
||||||
|
let savedScrollLeft = 0;
|
||||||
|
let savedScrollTop = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换全屏模式
|
||||||
|
* 需求 14.1: 点击全屏按钮将图表全屏显示
|
||||||
|
* 需求 14.2, 14.3: 全屏模式下保持缩放和拖拽功能可用
|
||||||
|
* 需求 14.5: 退出全屏恢复图表原始状态
|
||||||
|
*/
|
||||||
|
const toggleFullscreen = () => {
|
||||||
|
if (!isFullscreen) {
|
||||||
|
// 进入全屏
|
||||||
|
enterFullscreen();
|
||||||
|
} else {
|
||||||
|
// 退出全屏
|
||||||
|
exitFullscreen();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入全屏模式
|
||||||
|
*/
|
||||||
|
const enterFullscreen = () => {
|
||||||
|
// 保存当前状态
|
||||||
|
savedScale = scale;
|
||||||
|
savedScrollLeft = container.scrollLeft;
|
||||||
|
savedScrollTop = container.scrollTop;
|
||||||
|
|
||||||
|
// 添加全屏类
|
||||||
|
container.classList.add('mermaid-fullscreen');
|
||||||
|
isFullscreen = true;
|
||||||
|
|
||||||
|
// 更新全屏按钮
|
||||||
|
const fullscreenBtn = controls.querySelector('[data-action="fullscreen"]');
|
||||||
|
if (fullscreenBtn) {
|
||||||
|
fullscreenBtn.textContent = '⛶';
|
||||||
|
fullscreenBtn.title = '退出全屏';
|
||||||
|
fullscreenBtn.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 需求 14.3: 全屏模式下显示退出全屏按钮(已在工具栏中)
|
||||||
|
// 工具栏在全屏模式下仍然可见
|
||||||
|
|
||||||
|
// 禁用页面滚动
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
|
||||||
|
this.logDebug('进入全屏模式');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出全屏模式
|
||||||
|
* 需求 14.5: 恢复图表原始状态(缩放级别和位置)
|
||||||
|
*/
|
||||||
|
const exitFullscreen = () => {
|
||||||
|
// 移除全屏类
|
||||||
|
container.classList.remove('mermaid-fullscreen');
|
||||||
|
isFullscreen = false;
|
||||||
|
|
||||||
|
// 更新全屏按钮
|
||||||
|
const fullscreenBtn = controls.querySelector('[data-action="fullscreen"]');
|
||||||
|
if (fullscreenBtn) {
|
||||||
|
fullscreenBtn.textContent = '⛶';
|
||||||
|
fullscreenBtn.title = '全屏';
|
||||||
|
fullscreenBtn.classList.remove('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 恢复原始状态
|
||||||
|
scale = savedScale;
|
||||||
|
updateZoom(false);
|
||||||
|
|
||||||
|
// 恢复滚动位置
|
||||||
|
setTimeout(() => {
|
||||||
|
container.scrollLeft = savedScrollLeft;
|
||||||
|
container.scrollTop = savedScrollTop;
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
// 恢复页面滚动
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
|
||||||
|
this.logDebug('退出全屏模式');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 需求 14.4: 按 ESC 键退出全屏模式
|
||||||
|
const handleEscKey = (e) => {
|
||||||
|
if (e.key === 'Escape' && isFullscreen) {
|
||||||
|
exitFullscreen();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 绑定 ESC 键事件
|
||||||
|
document.addEventListener('keydown', handleEscKey);
|
||||||
|
|
||||||
|
// 清理函数(在容器销毁时调用)
|
||||||
|
container.dataset.cleanupFullscreen = 'registered';
|
||||||
|
container._fullscreenCleanup = () => {
|
||||||
|
document.removeEventListener('keydown', handleEscKey);
|
||||||
|
if (isFullscreen) {
|
||||||
|
exitFullscreen();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// 需求 16.2-16.4: 移动端触摸手势支持
|
// 需求 16.2-16.4: 移动端触摸手势支持
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|||||||
55
style.css
55
style.css
@@ -1135,6 +1135,61 @@ html.darkmode .mermaid-hint {
|
|||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 需求 14: Mermaid 全屏模式样式 */
|
||||||
|
.mermaid-fullscreen {
|
||||||
|
position: fixed !important;
|
||||||
|
top: 0 !important;
|
||||||
|
left: 0 !important;
|
||||||
|
right: 0 !important;
|
||||||
|
bottom: 0 !important;
|
||||||
|
width: 100vw !important;
|
||||||
|
height: 100vh !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 20px !important;
|
||||||
|
z-index: 99999 !important;
|
||||||
|
background: var(--color-foreground) !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.darkmode .mermaid-fullscreen {
|
||||||
|
background: var(--color-widgets) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 全屏模式下的工具栏 */
|
||||||
|
.mermaid-fullscreen .mermaid-zoom-controls {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.darkmode .mermaid-fullscreen .mermaid-zoom-controls {
|
||||||
|
background: rgba(30, 30, 30, 0.95);
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 全屏按钮激活状态 */
|
||||||
|
.mermaid-zoom-btn[data-action="fullscreen"].active {
|
||||||
|
background: rgba(94, 114, 228, 0.2);
|
||||||
|
color: var(--themecolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 全屏模式下的内部容器 */
|
||||||
|
.mermaid-fullscreen .mermaid-container-inner {
|
||||||
|
max-height: calc(100vh - 100px);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 全屏模式下的提示文本 */
|
||||||
|
.mermaid-fullscreen .mermaid-hint {
|
||||||
|
opacity: 1;
|
||||||
|
bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mermaid 淡入动画 */
|
/* Mermaid 淡入动画 */
|
||||||
@keyframes mermaidFadeIn {
|
@keyframes mermaidFadeIn {
|
||||||
from {
|
from {
|
||||||
|
|||||||
Reference in New Issue
Block a user