feat: 实现 Mermaid 主题自动同步功能
- 在 setDarkmode() 中触发 argon:theme-switched 事件 - 优化 reRenderCharts() 函数,保持图表缩放级别和滚动位置 - 添加淡入淡出过渡动画,提升视觉体验 - 只替换 SVG 内容,保留容器结构和控制按钮 - 主题切换失败时保持原样,不影响用户体验 需求:17.1, 17.2, 17.3, 17.4, 17.5
This commit is contained in:
@@ -36,10 +36,10 @@
|
||||
|
||||
### 阶段 2: Mermaid 显示效果优化
|
||||
|
||||
- [~] 5. 优化 Mermaid 工具栏
|
||||
- [ ] 5.1 实现工具栏自动隐藏 _需求:11.1, 11.2_
|
||||
- [ ] 5.2 优化工具栏样式(半透明背景) _需求:11.3-11.5_
|
||||
- [ ] 5.3 添加按钮提示(tooltip) _需求:20.2_
|
||||
- [x] 5. 优化 Mermaid 工具栏
|
||||
- [x] 5.1 实现工具栏自动隐藏 _需求:11.1, 11.2_
|
||||
- [x] 5.2 优化工具栏样式(半透明背景) _需求:11.3-11.5_
|
||||
- [x] 5.3 添加按钮提示(tooltip) _需求:20.2_
|
||||
|
||||
- [~] 6. 增强 Mermaid 缩放功能
|
||||
- [ ] 6.1 实现以鼠标为中心的缩放 _需求:12.1_
|
||||
@@ -72,10 +72,10 @@
|
||||
|
||||
### 阶段 4: Mermaid 主题和性能优化
|
||||
|
||||
- [~] 11. 优化 Mermaid 主题同步
|
||||
- [ ] 11.1 实现主题自动切换 _需求:17.1, 17.2_
|
||||
- [ ] 11.2 保持图表状态 _需求:17.3_
|
||||
- [ ] 11.3 添加主题切换动画 _需求:17.4, 17.5_
|
||||
- [x] 11. 优化 Mermaid 主题同步
|
||||
- [x] 11.1 实现主题自动切换 _需求:17.1, 17.2_
|
||||
- [x] 11.2 保持图表状态 _需求:17.3_
|
||||
- [x] 11.3 添加主题切换动画 _需求:17.4, 17.5_
|
||||
|
||||
- [~] 12. 优化 Mermaid 渲染性能
|
||||
- [ ] 12.1 实现批量渲染 _需求:18.1_
|
||||
|
||||
104
argontheme.js
104
argontheme.js
@@ -5700,6 +5700,8 @@ void 0;
|
||||
|
||||
/**
|
||||
* 重新渲染所有图表(主题切换时)
|
||||
* 需求 17.3: 保持图表的缩放级别和位置
|
||||
* 需求 17.4, 17.5: 使用淡入淡出过渡效果
|
||||
*/
|
||||
reRenderCharts() {
|
||||
// 只选择成功渲染的图表容器,排除错误容器
|
||||
@@ -5748,25 +5750,121 @@ void 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 需求 17.3: 保存当前的缩放级别和滚动位置
|
||||
const inner = chart.querySelector('.mermaid-container-inner');
|
||||
let savedState = null;
|
||||
|
||||
if (inner) {
|
||||
const transform = window.getComputedStyle(inner).transform;
|
||||
const scrollLeft = inner.scrollLeft;
|
||||
const scrollTop = inner.scrollTop;
|
||||
|
||||
// 提取缩放比例
|
||||
let scale = 1;
|
||||
if (transform && transform !== 'none') {
|
||||
const matrix = transform.match(/matrix\(([^)]+)\)/);
|
||||
if (matrix) {
|
||||
const values = matrix[1].split(',').map(v => parseFloat(v.trim()));
|
||||
scale = values[0]; // scaleX
|
||||
}
|
||||
}
|
||||
|
||||
savedState = {
|
||||
scale: scale,
|
||||
scrollLeft: scrollLeft,
|
||||
scrollTop: scrollTop
|
||||
};
|
||||
|
||||
this.logDebug('保存图表状态', savedState);
|
||||
}
|
||||
|
||||
const chartId = `mermaid-chart-rerender-${Date.now()}-${index}`;
|
||||
|
||||
// 需求 17.4: 添加淡出动画
|
||||
chart.style.transition = 'opacity 0.2s ease-out';
|
||||
chart.style.opacity = '0';
|
||||
|
||||
// 等待淡出完成后重新渲染
|
||||
setTimeout(() => {
|
||||
window.mermaid.render(`mermaid-svg-${chartId}`, code).then(result => {
|
||||
// 保存旧的内部容器引用
|
||||
const oldInner = chart.querySelector('.mermaid-container-inner');
|
||||
|
||||
// 更新 SVG 内容
|
||||
if (oldInner) {
|
||||
// 只替换 SVG,保留容器结构
|
||||
const oldSvg = oldInner.querySelector('svg');
|
||||
if (oldSvg) {
|
||||
// 创建临时容器解析新的 SVG
|
||||
const temp = document.createElement('div');
|
||||
temp.innerHTML = result.svg;
|
||||
const newSvg = temp.querySelector('svg');
|
||||
|
||||
if (newSvg) {
|
||||
// 替换 SVG
|
||||
oldSvg.replaceWith(newSvg);
|
||||
|
||||
// 确保 SVG 响应式
|
||||
newSvg.style.width = '100%';
|
||||
newSvg.style.height = 'auto';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果没有内部容器,直接替换内容
|
||||
chart.innerHTML = result.svg;
|
||||
chart.dataset.currentTheme = newTheme;
|
||||
|
||||
// 确保 SVG 响应式
|
||||
const svg = chart.querySelector('svg');
|
||||
if (svg) {
|
||||
svg.style.maxWidth = '100%';
|
||||
svg.style.width = '100%';
|
||||
svg.style.height = 'auto';
|
||||
}
|
||||
}
|
||||
|
||||
// 更新主题标记
|
||||
chart.dataset.currentTheme = newTheme;
|
||||
|
||||
// 需求 17.3: 恢复缩放级别和滚动位置
|
||||
if (savedState && oldInner) {
|
||||
// 恢复缩放
|
||||
oldInner.style.transform = `scale(${savedState.scale})`;
|
||||
|
||||
// 恢复滚动位置
|
||||
oldInner.scrollLeft = savedState.scrollLeft;
|
||||
oldInner.scrollTop = savedState.scrollTop;
|
||||
|
||||
// 更新缩放显示
|
||||
const zoomLevel = chart.querySelector('.mermaid-zoom-level');
|
||||
if (zoomLevel) {
|
||||
zoomLevel.textContent = Math.round(savedState.scale * 100) + '%';
|
||||
}
|
||||
|
||||
this.logDebug('恢复图表状态', savedState);
|
||||
}
|
||||
|
||||
// 需求 17.5: 添加淡入动画
|
||||
requestAnimationFrame(() => {
|
||||
chart.style.transition = 'opacity 0.3s ease-in';
|
||||
chart.style.opacity = '1';
|
||||
|
||||
// 动画完成后清理过渡样式
|
||||
setTimeout(() => {
|
||||
chart.style.transition = '';
|
||||
}, 300);
|
||||
});
|
||||
|
||||
this.logDebug(`图表重新渲染成功: ${chartId}`);
|
||||
}).catch(error => {
|
||||
this.logError('图表重新渲染失败', error);
|
||||
// 重新渲染失败时,不替换为错误容器,保持原样
|
||||
|
||||
// 重新渲染失败时,恢复显示
|
||||
chart.style.opacity = '1';
|
||||
chart.style.transition = '';
|
||||
|
||||
// 不替换为错误容器,保持原样
|
||||
// 因为之前已经成功渲染过,只是主题切换失败
|
||||
});
|
||||
}, 200); // 等待淡出动画完成
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
|
||||
@@ -528,6 +528,11 @@
|
||||
|
||||
}
|
||||
|
||||
// 触发主题切换事件(用于 Mermaid 等组件响应主题变化)
|
||||
document.dispatchEvent(new CustomEvent('argon:theme-switched', {
|
||||
detail: { darkmode: enable }
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
function toggleDarkmode(){
|
||||
|
||||
Reference in New Issue
Block a user