# Visioxure **Repository Path**: masonwu21/Visioxure ## Basic Information - **Project Name**: Visioxure - **Description**: No description available - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-10-28 - **Last Updated**: 2026-11-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Visioxure Visio + Axure 结合体的桌面原型设计工具:**画得出 Visio 的图,也能像 Axure 一样跑交互**。 - 桌面端:C++17 / Win32 / WebView2(TauriCPP 框架)+ Canvas 2D 前端,单 exe 分发 - 当前版本:**1.2.0**(exe 文件属性同步带版本信息,状态栏右下角也显示版本号) - 文档模型:前端 JSON 为唯一事实源,后端只做文件 IO 与 VSDX 编解码 - 文件格式:`.vsdx`(OPC 包 + VisioML),保存后可用 Microsoft Visio 直接打开 ## 当前进度 | 阶段 | 内容 | 状态 | |---|---|---| | P0 | 窗口骨架 + Bridge 双向通信 | ✅ | | P1 | 画布/选择/变换/文本/撤销重做/多页面/参考线/标尺 | ✅ | | P2 | 路径与布尔运算、组合/解组、连接线与布线、形状库、图层、对齐分布 | ✅ | | P3 | VSDX 读写(miniz)、文件对话框、脏标记、最近文件、Ctrl+S | ✅ | | P4 | 交互面板(事件→动作)、动态面板多状态、三级变量、F5 浏览器预览 | ✅ | | P5 | 注释 / 链接 / 脚本面板、meta 读写 | ✅ | | P5.5 | 形状属性面板(几何 + 文本样式)、前端 Playwright 验收 | ✅ | | P6 | 导出 PNG / SVG / HTML / PDF(S1) | ✅(多页 zip 待 A1) | | P7 | 主题、性能、图标、测试补齐、文档 | ⏳(应用图标已完成) | 详细设计见 [CODEPLAN.md](CODEPLAN.md)。 ## 1.2.0(2026-11) - **版本号 1.2.0**:仍由 `CMakeLists.txt` 的 `project(VERSION)` 单一来源派生到 exe 文件属性、状态栏与 VSDX `AppVersion` - **动态面板完善**:状态编辑页签(标题 = 面板名 + 状态名,可切换/关闭)、状态复制/排序/删除与形状 id 重映射;移动面板带动全部状态内容,视口裁剪可开关(旧文档默认不裁剪)、一键适应内容尺寸;状态编辑中点插的形状自动落在面板视口内 - **状态切换**:`setState` 支持指定 / 下一个 / 上一个 / 循环,淡入淡出与四向滑动动效、时长;新增 `statechange` 事件与 `{{panelStateName}}` 等局部变量;页面载入 / 按键事件只派发给当前可见状态 - **旧文档兼容**:载入时把旧交互面板丢失的 `setState` 空状态物化为明确状态 id;交互面板给出「目标 = 当前默认态 / 只有 1 个状态 / 状态为空」等诊断;导出 HTML 带 `visioxure-runtime` 指纹以识别旧运行时 - **F5 浏览器预览**:菜单栏最右侧新增「预览」按钮,直接把工程导出为自包含 HTML 写到系统临时目录,并用默认浏览器新页签打开;不弹保存对话框,无 Bridge 时退化为 Blob URL 新页签 - **剪贴板复制粘贴**:`Ctrl+C` / `Ctrl+V` 复制粘贴图形,支持多选、跨页 / 跨动态面板状态、连续粘贴阶梯错开与 `Ctrl+Z` 撤销;`Ctrl+D` 再制保留,文本输入框和就地文字编辑仍是原生复制粘贴 - **画布右键菜单**:多选时「组合」、选中组合或处于组编辑态时「取消组合」,不可用的项灰显;组合 / 解组统一作用于当前编辑容器,不再把动态面板状态内的形状组合到页面顶层 - **缩放显示修复**:工具栏中间的百分比不再固定 `100%`,与底部状态栏同源,缩放按钮 / `Ctrl`+滚轮 / 适应窗口都会同步刷新 - **交互组件缩放修复**:组合缩放改为以拖拽开始时的深拷贝快照逐帧重算,消除逐帧连乘导致的子形状漂移;形状库组合内的 `path` 图标 / 箭头插入时固化 `path.design`,缩放时几何随包围盒变化;子形状文字字号与圆角按等比系数跟随,全程可 `Ctrl+Z` 恢复 - **动态面板虚线框可选中**:命中判定不再只认状态内子形状,空面板、框内空白与 1px 虚线框(含状态编辑态蓝色框)都能选中面板本身;框线留 6 屏幕像素容差,开启裁剪时视口外仍不命中、关闭裁剪时溢出子形状照旧可点 - **动态面板状态编辑修复**:画布渲染改用 `panelEdit.stateId`,切换状态页签后新加的组件立刻可见;点插与拖拽的落点统一钳制在面板视口内,连点级联按「页面 / 面板状态」隔离并在可用空间内回绕,不再出现「插入了、退出编辑却看不见」 - **状态编辑遮罩**:进入动态面板状态编辑时,画布上面板视口以外的区域压暗(视口与「状态编辑」标签留亮),Esc / 关闭页签退出后自动恢复 - **验收**:Playwright e2e 226 项断言(含真实样本导出点击)、CTest VSDX 往返与临时预览文件落盘测试;上述剪贴板、右键菜单、缩放同步、组件缩放、状态编辑插入与遮罩另有针对性 Playwright 验证(含像素级断言) ## 近期更新(2026-10) - **版本号升至 1.1.0**:状态栏右下角改为「版本号 + GitHub/Gitee 图标链接」,两个仓库链接从菜单栏左侧移到这里,点击仍由系统默认浏览器打开 - **形状库支持拖拽插入**:条目可直接拖到画布上,形状中心落在鼠标释放处(拖拽中缩略图跟随光标、画布虚线提示落点,拖回面板即取消);点击插入仍然落在视口中心,同一位置连点时自动阶梯错位 20px(最多 8 步后回到原位),不再与上一个形状完全重叠 - **版本号 1.0.1**:状态栏右下角常显版本号(`v1.0.1`,桌面端由后端 `app.get_info` 从 CMake 的 `project(VERSION)` 回填);同时去掉此前占据右下角的 Bridge 连接状态提示 - **页面网格样式**:右侧「页面」面板新增「网格」四档——小网格(10px 细线)/ 大网格(10px 细线 + 每 50px 主线)/ 网点 / 无;逐页保存、随 .vsdx 往返(PageSheet 的 `User.VXGrid`),选「无」同时关闭网格吸附;状态栏点「网格」也能在四档间循环 - **表格组件**:形状库新增「表格」(组 + 等分网格),右侧「属性」可选行数 / 列数(1–30)与首行表头;拖缩放手柄时按网格重排而不是拉伸单元格,行高 / 列宽有可读下限(24 / 48px),压到下限即停,缩放与改行列均可 Ctrl+Z - **占位组件改版**:图片占位 / 照片占位按 `prototype/` 样图重绘(140×100 卡片 + 山形图标、76×76 头像剪影) - **状态栏常显当前页**:底部状态栏新增「页面 xxx」,左侧面板切到形状库时也知道自己在改哪一页;点一下切回「页面树」 - **页面树改造**:行首页图标改为拖拽把手(上下拖动排序,可撤销)、顶部新增「新增页面」按钮、去掉底部提示行 - **导出 HTML**:页面树移到左侧可折叠侧栏(200px ⇄ 34px),点页面名切页;修复导出页面底色未铺导致整页发灰(新增空白像素回归断言) - 页面纸张默认背景色统一为白色(新建页面 / 新建文档 / 旧文件与未声明底色的 VSDX 都回退白纸) - 「适应窗口」改为页面贴工作区左上角,多余空间留在右侧与下方 - 应用图标:`TauriCPP/tools/make_icon.py` 从 `logo.svg` / `logo.png` 生成 `src/app.ico`,编译期嵌入 exe 并设为窗口类图标 - **导出(P6-S1)**:一级菜单「导出」(位于「文件」右侧)提供四种产物——**PNG**(当前页,1x/2x/3x 与透明底)、**SVG**(当前页矢量)、**HTML**(整个工程,单文件自包含可交互)、**PDF**(整个工程多页);位图 / 矢量 / 栅格 PDF / 交互页全部复用与编辑器同一份 `drawScene`/`interact.js`,导出与画布逐像素一致;后端 `export.write` 负责 base64 解码落盘,无原生 Bridge 时退化为浏览器下载;验收 `test/e2e/check_export.js`(65 项) - 新增右侧「属性」面板:X / Y / 宽 / 高 / 旋转 / 圆角 / 不透明度,以及字体 / 字号 / 加粗 / 字色 / 水平·垂直对齐;多选时不一致的值显示「多个值」,回车或失焦生效,全部可 Ctrl+Z 撤销 - 修复在面板输入框里改完数值后 Ctrl+Z 失效(面板抢占了全局快捷键) - 修复撤销 / 重做后丢失当前页与选中(快照现在同时记录页面与选中上下文) - 修复形状库的三角形 / 梯形 / 菱形 / 箭头插入后缺一条闭合边:子路径开合不再按「有没有填充」推断,改由 `path.closed[]` 显式声明(缺省闭合),`.vsdx` 读写同步保留该语义 - 修复菱形 / 三角形 / 梯形「选框变低但图形不变」:拖缩放手柄、面板改宽高、组缩放与布尔运算输入现在都按包围盒相对设计尺寸(`path.design`)缩放图形,`.vsdx` 导出同步(旧文件与导入的 Visio 文件行为不变) - 新增 `test/e2e/` Playwright 验收脚本(属性面板 + 主干交互 + 子路径闭合 + 路径缩放,共 88 项断言,复用本机 Edge,无需下载浏览器内核) - 形状库改版:基本形状 6 项(矩形 / 圆角矩形 / 圆形 / 三角形 / 梯形 / 菱形,带连接点)、流程图 3 项(连接线 / 箭头 / 双向箭头)、交互原型 25 项(按 `prototype/` 样图重做,白底卡片 + 极细描边 + 深墨蓝主色 + 骨架占位),固定三列 - 菜单栏左侧改为 GitHub / Gitee 图标链接(内容取自 `logo.txt`),点击由系统默认浏览器打开 - 新增右侧「样式」面板与 Office 风格调色板:填充 / 边框 / 线宽,主题色 + 标准色 + 取色器 + 最近自定义色 - 连接线支持直线 / 折线 / 曲线、线宽、两端 7 种箭头,端点可拖拽并接近吸附 - 修复拖动连接线端点后整条连接线消失(布线空值异常导致整帧渲染中断) - 修复无填充形状双击输入文字后不可见 ## 功能一览 **绘图(Visio 向)** - 矩形 / 圆角矩形 / 椭圆 / 文本 / 图片 / 自由路径(含孔洞,even-odd) - 组合(Ctrl+G)/ 解组(Ctrl+Shift+G)、布尔运算(联合 / 相交 / 剪除,基于 Clipper);画布右键菜单也提供「组合 / 取消组合」,多选或进入组编辑态时按条件启用,组合结果落在当前编辑容器(页面 / 动态面板状态) - 剪贴板:`Ctrl+C` / `Ctrl+V` 复制粘贴图形(多选、跨页 / 跨面板状态、连续粘贴阶梯错开、可 `Ctrl+Z` 撤销),`Ctrl+D` 再制保留;文本输入框与就地文字编辑仍是原生复制粘贴 - 连接线:四边连接点吸附、直线 / 直角折线 / 曲线、线宽、两端 7 种箭头(无 / 实心 / 开口 / 空心三角 / 圆点 / 菱形 / 竖线)、移动形状自动跟随 - 连接线端点可直接拖拽换连接点(14px 接近吸附),**选中后可拖拽任意线段手动调整折线** - 形状库:基本形状(矩形 / 圆角矩形 / 圆形 / 三角形 / 梯形 / 菱形)、流程图(连接线 / 箭头 / 双向箭头)、交互原型(26 个 Axure 风格构件:手机画板 / 按钮 / 表单控件 / **表格** / 占位图 / 卡片 / 对话框 / 动态面板等);固定三列,缩略图与插入结果一致(基本形状统一黑描边无填充,交互原型按样图配色);点击插入到视口中心(连点自动错位),也可拖拽到画布任意位置插入 - 交互原型组件可整体拖拽缩放:子形状按拖拽起始快照线性映射,组合内 `path` 图标、文字字号与圆角同步跟随,多帧拖拽不再累积漂移或变形 - 右侧「属性」面板:位置尺寸 / 旋转 / 圆角 / 不透明度 + 字体 / 字号 / 加粗 / 字色 / 水平·垂直对齐(多选混合值显示「多个值」) - 右侧「样式」面板:填充 / 边框颜色(Office 主题色 + 标准色 + 取色器 + 最近 10 个自定义色)、线宽、连接线线型与箭头 - 双击形状就地输入文字(无填充形状自动改用深色字) - 图层显隐与锁定、网格与参考线吸附、多页面页面树(拖动把手排序 / 一键新增页面) - 右侧「页面」面板:页面尺寸、背景色与网格样式(小 / 大 / 网点 / 无);底部状态栏始终显示当前编辑的页面 **VSDX 读写(P3/P4)** - 保存:可以生成结构合法的 VSDX,Visio 打开后形状 / 文字 / 颜色 / 连线正确 - 打开:支持真实 Visio 文件(样式表继承、母版几何、原生组合、相对坐标、1-D 连接线、背景页跳过) - 自定义数据通过 User 段保存:组合链、连接线粘附、手动折线、交互、面板状态、变量 **交互原型(Axure 向,P4)** - 右侧「交互」Tab:事件 → 动作编辑器;全局变量 / 页面变量编辑 - 事件:点击 / 双击 / 鼠标移入 / 移出 / 页面载入 / 按键 / 状态改变(动态面板) - 动作:打开链接(跳页或 URL)/ 显示 / 隐藏(含淡入淡出)/ 切换面板状态 / 设置文本 / 移动(可带动画)/ 设置变量 / 运行脚本 - 动态面板:双击(或属性/交互面板按钮)在画布上方打开**状态编辑页签**,页签标题为面板名 + 状态名,可重命名面板、切回页面页签、关闭页签;状态栏同步显示「页面 › 面板 › 状态」面包屑 - 动态面板:多状态编辑(新增 / 复制 / 排序 / 删除)与切换(指定 / 上一下一个 / 循环,淡入淡出或四向滑动);新建形状归入当前状态,点插时自动落在面板视口内;面板移动带动全部状态内容,视口裁剪可开关(旧文档默认不裁剪)、可一键适应内容尺寸;状态切换触发 OnStateChange,可用 `{{panelStateName}}` 等变量 - 动态面板状态编辑:虚线框(含空面板与框内空白)可直接点击选中,编辑时渲染的就是正在编辑的状态;点插 / 拖拽添加的组件统一钳制在视口内并立刻可见,画布上面板视口以外的区域压暗,退出编辑恢复 - 交互只在 **F5 预览 / 导出的 HTML** 中执行;编辑器里点击形状只会选中它。设计态(画布与导出显示的默认状态)在「交互」面板的状态单选里切换 - 变量插值 `{{name}}`:local → page → global,全局变量跨页持久、页面变量进入页面时重置 - **预览(菜单栏最右侧按钮 / F5)**:把整个工程导出为自包含 HTML 写到系统临时目录,并用系统默认浏览器新页签打开,不弹保存对话框;浏览器直开(无 Bridge)时退化为 Blob URL 新页签 - 应用内全屏预览运行时仍保留(`VX.Preview`),与 HTML 导出共用同一交互运行时,Esc 退出 **导出(P6-S1)** - PNG(当前页):1x / 2x / 3x、透明底;离屏复用 `drawScene`,与画布逐像素一致(不吃编辑态最小线宽、不带页影/页框) - SVG(当前页):矢量,与渲染器同口径的圆角 / 虚线 / 箭头 / 多行文本;隐藏层不参与导出 - HTML(整个工程):单文件自包含,内联运行时脚本 + 文档 JSON + 样式,双击即可跑交互、切页、`{{变量}}` 插值;页面树在左侧可折叠侧栏 - HTML 产物带 `` 指纹。改过前端后必须重新构建 exe(`./build.ps1`)或用 `-DevMode` 运行,否则已编译 exe 仍内嵌旧运行时,导出的 HTML 不会带上新逻辑;旧版导出的 HTML 需要重新导出 - 打开旧文档时会把 `setState` 动作里丢失的空状态(旧交互面板只显示不写回)物化为明确的状态 id,避免「按钮点了没反应」 - PDF(整个工程):多页单文件,每页一张 JPEG 以 `DCTDecode` 内嵌,屏幕 96dpi → PDF 72pt(1px=0.75pt) ## 构建与运行 ### 环境 - Windows 10/11 - Visual Studio 2022(C++ 桌面工作负载) - CMake 3.15+ - Python 3(前端资源打包进 `.rc`) - vcpkg 静态库:`webview2:x64-windows-static` ### 命令 ```powershell # 构建 Release(内部调用 CMake + MSBuild) powershell -ExecutionPolicy Bypass -File .\build.ps1 # 产物 build\Release\Visioxure.exe ``` 首次构建会自动把 `frontend/` 下的 HTML/CSS/JS 打包进资源;修改前端后需重新构建。 只调 UI 时可用开发模式(前端从 `frontend/` 目录直接加载,无需重新编译): ```powershell powershell -ExecutionPolicy Bypass -File .\build.ps1 -DevMode ``` ### 测试 ```powershell cd build ctest -C Release --output-on-failure ``` - `vsdx_test`:JSON → VSDX → JSON 往返一致性、包结构断言、坐标 Y 翻转、组合/连接线粘附/二次往返 - 样例文件在 `test/sample/`(Visio 生成的原生 VSDX 与对应 SVG,可用于读取回归与渲染对照) ### 升级版本号 当前版本 **1.2.0**。`CMakeLists.txt` 的 `project(Visioxure VERSION x.y.z)` 是唯一来源,exe「文件属性 → 详细信息」、`app.get_info`(状态栏显示)与 VSDX `AppVersion` 都由它自动派生。升级时改这一处,并同步两处静态兜底值: - `src/version.hpp`:`VISIOXURE_VERSION` 回退值(不经 CMake 手工编译时使用) - `frontend/index.html`:`#app-version`(浏览器直开、无 Bridge 时显示) 改完重新执行 `build.ps1`;README 顶部的「当前版本」与 `CODEPLAN.md` 的版本表也要同步。 ## 目录结构 ``` src/ 应用入口 + VSDX 编解码 main.cpp Bridge 命令:文件对话框 / vsdx.save / vsdx.load / 最近文件 vsdx/ xml(极简 DOM) / package(OPC) / writer / reader frontend/ 前端(编译期嵌入 exe) index.html 菜单 / 工具栏 / 三栏布局 js/model.js 文档模型(页面 / 形状 / 面板 / 图层 / 变量) js/canvas/ viewport / hit / renderer / overlay js/tools.js 选择 / 创建 / 连接线 / 线段与端点拖拽 js/stencils.js 形状库(分类 / 缩略图 / 插入) js/table.js 表格组件(行列数 / 等分网格 / 最小行高列宽) js/style.js 右侧「样式」面板(填充 / 边框 / 连接线属性) js/colorpicker.js Office 风格调色板(主题色 / 标准色 / 自定义 / 最近颜色) js/editor.js 快捷键 / 菜单 / 页面树 / 状态栏 js/interact.js 交互运行时(事件 → 动作、变量、动效) js/preview.js F5 预览 js/inspect.js 右侧「交互」面板 js/fileio.js 打开 / 保存 / 脏标记 / 最近文件 TauriCPP/ 窗口 + WebView2 + Bridge 框架(随仓库提供) third_party/miniz/ 单文件 zip 库(OPC 打包) test/ vsdx_test 与 Visio 原生样例 ``` ## 技术要点 - **坐标**:内部 96 DPI、左上原点、Y 向下;Visio 为英寸、左下原点、Y 向上,写入/读取时做 Pin 与角度翻转 - **布线**:端口法向 + LEAD 出线段 + 折线算法(曲线则为三次贝塞尔采样),折线统一做去重与「去折返」整理,避免线段自我重叠;编辑器与 VSDX 输出一致 - **渲染健壮性**:单个形状绘制异常不会中断整帧(逐形状 try/catch);老版本 WebView2 缺少 `ctx.roundRect` 时退化为手写圆角路径,细线在小比例下保持至少 1 屏幕像素 - **母版**:按母版自身宽高解析 Geometry,再缩放到页面形状;页面行覆盖按 IX 合并 - **持久化**:交互 / 面板 / 变量以 User 单元格 JSON 保存,Visio 侧仅作为不可见数据,不影响打开 ## 已知限制 - 圆弧 / 贝塞尔按折线近似:胶囊形会显示为圆角矩形,虚线边框绘制为实线 - 连接线走自研直角折线算法,个别长连线与 Visio 内置走向不同(可手动分段调整) - 曲线连接线导出 VSDX 时按折线写入;箭头种类导出目前只区分有 / 无,统一写成实心三角 - 只导入非背景页;背景页内容不合并 - 组合级交互不随保存写入 - 富文本多段落只保留首段样式 ## 仓库 - Gitee:https://gitee.com/masonwu21/Visioxure - GitHub:https://github.com/Emsoro/Visioxure `TauriCPP` 框架自带其 LICENSE,见 [TauriCPP/LICENSE](TauriCPP/LICENSE)。 ## 打赏 如果 Visioxure 对你有帮助,欢迎请作者喝杯咖啡。 打赏