
1. 项目概述最近在整理技术文档时发现一个痛点如何快速绘制清晰美观的软件架构图市面上的工具要么太重如Visio要么需要学习复杂语法如PlantUML要么依赖特定平台。于是我开发了一个基于纯原生Web技术的Markdown架构图生成器完全开源且零依赖。这个工具的核心特点是使用简单的Markdown语法定义架构层次支持横向(row)和纵向(col)两种布局模式具备无限画布交互功能拖拽平移鼠标中心缩放实时预览样式自定义响应式设计纯前端实现一个HTML文件搞定所有功能2. 核心功能解析2.1 Markdown语法解析工具采用极简的Markdown语法定义架构# 层级标题 [布局方向] - 模块名称: 模块描述 - 模块名称: 模块描述布局指令说明row模块横向排列适合展示同级服务col模块纵向排列默认适合展示调用链实现原理通过正则表达式/^#(.?)(row|col)?/匹配标题行使用字符串分割处理模块描述构建层级化的JSON数据结构2.2 智能布局引擎横向布局算法// 计算模块宽度 const availableWidth layerWidth - 2*padding - (count-1)*gap const modWidth count 0 ? availableWidth / count : 0 // 定位模块 layer.modules.forEach((mod, mIdx) { const modX padding mIdx*(modWidth gap) const modY currentY 55 drawModule(modX, modY, modWidth, moduleHeight, mod) })纵向布局算法layer.modules.forEach((mod, mIdx) { const modX padding const modY currentY 50 (mIdx*(moduleHeight 10)) const modWidth layerWidth - 2*padding drawModule(modX, modY, modWidth, moduleHeight, mod) })2.3 无限画布实现关键技术点使用Canvas 2D的transform矩阵维护scale和offset状态滚轮缩放时重新计算视口中心核心代码// 滚轮缩放处理 container.addEventListener(wheel, (e) { const rect canvas.getBoundingClientRect() const mouseX e.clientX - rect.left const mouseY e.clientY - rect.top const zoomFactor e.deltaY 0 ? 0.9 : 1.1 // 关键公式保持鼠标位置内容不变 offsetX mouseX - (mouseX - offsetX)*zoomFactor offsetY mouseY - (mouseY - offsetY)*zoomFactor scale * zoomFactor draw() })3. 使用指南3.1 快速开始克隆仓库或下载HTML文件浏览器直接打开index.html左侧编辑Markdown右侧实时预览3.2 样式自定义支持调整画布背景色模块填充色模块边框色模块文字色提示使用相近色系如蓝色系能让架构图更专业3.3 导出图片目前支持两种方式浏览器开发者工具截图F12 → 截图功能系统截图工具如Snipaste4. 技术实现细节4.1 核心架构graph TD A[Markdown输入] -- B[语法解析器] B -- C[布局引擎] C -- D[Canvas渲染] D -- E[交互处理]4.2 关键算法网格背景绘制function drawGrid() { const gridSize 40 * scale const startX (offsetX % gridSize) - gridSize const startY (offsetY % gridSize) - gridSize ctx.beginPath() for(let xstartX; xcanvas.width; xgridSize) { ctx.moveTo(x,0); ctx.lineTo(x,canvas.height) } // 纵线绘制同理... ctx.stroke() }模块渲染优化使用ctx.roundRect绘制圆角矩形通过clip()防止文字溢出采用shadowColor实现柔和阴影5. 扩展开发指南5.1 添加新功能推荐扩展方向PNG导出功能使用canvas.toDataURL节点拖拽编辑需实现碰撞检测自定义连接线需要路径计算算法5.2 修改布局算法关键函数parseText()文本解析入口draw()主绘制流程drawModule()单个模块渲染5.3 样式定制修改style标签中的CSS变量:root { --module-bg: #e3f2fd; --module-border: #2196f3; --text-color: #0d47a1; }6. 性能优化建议节流渲染对resize和input事件添加100ms延迟let renderTimer input.addEventListener(input, () { clearTimeout(renderTimer) renderTimer setTimeout(draw, 100) })离屏Canvas复杂架构可预渲染到隐藏Canvas分层渲染将网格背景与模块分层绘制7. 常见问题排查7.1 文字显示不全解决方案检查ctx.clip()是否正确应用调整模块内边距padding减小字体大小或增加模块高度7.2 缩放卡顿优化方向降低网格密度简化阴影效果使用requestAnimationFrame7.3 浏览器兼容性已知问题Safari对roundRect支持较晚需polyfill旧版Edge可能需启用实验性功能8. 设计思考与演进最初版本仅支持静态渲染经过三次迭代才加入动态布局方向v0.2无限画布交互v0.5实时样式配置v1.0关键决策点放弃使用第三方库如D3.js以保持轻量采用Markdown而非JSON作为输入格式优先实现核心功能而非完美UI9. 应用场景案例9.1 微服务架构文档# 网关层 row - API Gateway: 路由鉴权 - Load Balancer: 流量分发 # 业务服务 col - 用户服务: 用户管理 - 订单服务: 交易处理 - 支付服务: 第三方对接9.2 前端项目结构# 应用架构 col - 组件层: React/Vue组件 - 状态管理: Redux/Pinia - API层: Axios封装9.3 系统部署拓扑# 生产环境 row - Web服务器: Nginx集群 - 应用服务器: Docker Swarm - 数据库: MySQL主从10. 同类方案对比特性本工具PlantUMLDraw.io学习成本低中中交互性高无高部署复杂度零需Java环境需注册定制灵活性代码级语法限制UI限制实时协作否否是11. 开发心得Canvas坐标系理解全局坐标与局部坐标的转换是关键矩阵变换掌握translatescale的组合运用事件处理注意移除监听器防止内存泄漏响应式设计监听resize事件时要防抖踩坑记录最初未考虑缩放时的文字清晰度后来发现需要根据scale动态调整字体大小12. 未来规划增加导出为SVG功能支持模块折叠/展开添加箭头连线功能实现本地存储自动保存这个项目完全开源欢迎在GitHub上提交PR或issue。对于想要学习Canvas和前端架构的开发者代码中包含详细注释是非常好的学习素材。