Affected area
Desktop UI (agent-gui / React)
Version or commit
main@89f5e2b0(修复前版本)
Environment
OS:macOS 27.0(Apple Silicon / arm64)
部署方式:Tauri 桌面应用
WebView:WKWebView
影响范围:Markdown 中的 Mermaid 全屏查看器
模型供应商:不相关
Steps to reproduce
前置条件
使用 main@89f5e2b0 或包含旧版 Streamdown Mermaid 全屏实现的构建,在 macOS Tauri 桌面应用中准备一条包含以下 Mermaid 代码的 Markdown 消息:
flowchart LR
A[用户输入] --> B{参数校验}
B -->|通过| C[执行任务]
B -->|失败| D[返回错误]
C --> E[完成]
Loading
复现步骤
启动 LiveAgent Tauri 桌面应用,打开包含上述图表的 Markdown 消息。
点击 Mermaid 图表右上角的全屏按钮。
先保持 1x,观察文字、边框和连线是否清晰。
使用缩放按钮或鼠标滚轮连续放大到 150% 以上。
在图表上按住鼠标拖动一段距离,然后松开。
分别在以下三个阶段观察图表:
鼠标未按下、图表静止时;
按住并拖动时;
松开鼠标、图表再次静止后。
复现结果
图表整体出现低分辨率模糊,范围包括 SVG 文字、节点边框、连线和箭头,不只是 foreignObject 文本。
鼠标按下或拖动期间,图表有时会短暂变清晰。
松开鼠标后,图表通常再次变模糊;连续缩放后现象更明显。
同一份 Markdown 在 Chromium 中通常无法稳定复现该问题,必须以实际 Tauri WKWebView 结果为准。
Expected behavior
Mermaid 图表应始终保持 SVG 矢量渲染;在 1x、连续缩放、拖动及松开鼠标后,文字、边框、连线和箭头均应保持清晰,且缩放中心和拖动位置正确。
Actual behavior
Streamdown 的 PanZoom 即使在 1x 也会为 SVG 写入 transform: translate(...) scale(1) 与 will-change: transform。全屏 Portal 和嵌套 SVG 的合成层规则会让 WKWebView 提前把整张 SVG 栅格化为低分辨率合成纹理;后续 CSS 缩放实际是在拉伸旧纹理,因此整张图表都会模糊。
旧实现中,鼠标按下时的 CSS :active 状态可能暂时改变合成层,迫使 WebKit 重新栅格化,所以会出现“按住时清晰、松开后模糊”的假象。这不是稳定修复,静止状态仍依赖缓存纹理。
解决思路
只接管 Mermaid 的全屏入口,保留 Streamdown 的内嵌 Mermaid 渲染、复制按钮、只读限制和 securityLevel: "strict" 安全链路。
全屏组件继续使用同一个 Mermaid 渲染 API 生成标准 SVG,并通过 DOMParser 挂载 SVG,不修改压缩后的 Streamdown 依赖包。
移除全屏缩放链路对 CSS transform: scale() 的依赖,改为修改 SVG viewBox:缩放时以中心点调整坐标范围,拖动时把屏幕像素位移换算为 SVG 坐标位移。
保持 SVG 和容器 transform: none,让浏览器每次按矢量坐标重新绘制,而不是放大已缓存的合成纹理。
流式重新渲染时清理旧 SVG;工具栏按钮与拖拽 pointer 事件隔离,避免点击缩放/关闭被误判为拖动。
将 viewBox 解析、居中缩放和拖动换算提取为纯函数,并覆盖 1x、2x 中心不变及像素拖动换算测试。
Logs / screenshots
无相关运行时错误日志。
该问题仅在实际 Tauri WKWebView 中稳定复现;Chromium 用于验证 DOM 结构和交互,不替代 WKWebView 的清晰度验证。
修复后的运行预览见 Issue 评论 。
修复后的验证结果:全屏缩放、拖动和重置只改变 SVG viewBox,SVG 与容器的计算样式均为 transform: none;实际 WKWebView 中静止、拖动和松开后均保持清晰。
Pre-submit checklist
Affected area
Desktop UI (agent-gui / React)
Version or commit
main@89f5e2b0(修复前版本)Environment
Steps to reproduce
前置条件
使用
main@89f5e2b0或包含旧版 Streamdown Mermaid 全屏实现的构建,在 macOS Tauri 桌面应用中准备一条包含以下 Mermaid 代码的 Markdown 消息:flowchart LR A[用户输入] --> B{参数校验} B -->|通过| C[执行任务] B -->|失败| D[返回错误] C --> E[完成]复现步骤
1x,观察文字、边框和连线是否清晰。150%以上。复现结果
foreignObject文本。Expected behavior
Mermaid 图表应始终保持 SVG 矢量渲染;在
1x、连续缩放、拖动及松开鼠标后,文字、边框、连线和箭头均应保持清晰,且缩放中心和拖动位置正确。Actual behavior
Streamdown 的 PanZoom 即使在
1x也会为 SVG 写入transform: translate(...) scale(1)与will-change: transform。全屏 Portal 和嵌套 SVG 的合成层规则会让 WKWebView 提前把整张 SVG 栅格化为低分辨率合成纹理;后续 CSS 缩放实际是在拉伸旧纹理,因此整张图表都会模糊。旧实现中,鼠标按下时的 CSS
:active状态可能暂时改变合成层,迫使 WebKit 重新栅格化,所以会出现“按住时清晰、松开后模糊”的假象。这不是稳定修复,静止状态仍依赖缓存纹理。解决思路
securityLevel: "strict"安全链路。DOMParser挂载 SVG,不修改压缩后的 Streamdown 依赖包。transform: scale()的依赖,改为修改 SVGviewBox:缩放时以中心点调整坐标范围,拖动时把屏幕像素位移换算为 SVG 坐标位移。transform: none,让浏览器每次按矢量坐标重新绘制,而不是放大已缓存的合成纹理。viewBox解析、居中缩放和拖动换算提取为纯函数,并覆盖1x、2x中心不变及像素拖动换算测试。Logs / screenshots
viewBox,SVG 与容器的计算样式均为transform: none;实际 WKWebView 中静止、拖动和松开后均保持清晰。Pre-submit checklist