seatmap-editor

基于 Vue 3 与 Konva 的场馆绘座与选座编辑器:区域绘制、复合区域孔洞、DXF/SVG 导入、票档分配与分阶段发布计划。
177
Install
npm install seatmap-editor
Latest Version:0.2.0
Vue:3
License:MIT
Last Updated:Sep 16, 2026
Links: GitHub  ·  npm
Maintainer: zoroikuzo

seatmap-editor

基于 Vue 3 与 Konva 的场馆绘座与选座编辑器。

An open-source venue seating editor built with Vue 3 and Konva — region drawing, compound holes, DXF/SVG import, price levels and staged release plans.

License: MIT Vue 3 Konva


这是什么

一个可以直接运行的场馆座位图编辑器,用来把 CAD 图纸或 SVG 平面图变成可交互的选座业务数据: 绘制区域与座位、划分票档、配置分阶段开放计划,并导出 JSON 草稿交给业务端渲染选座页。

仓库自带完整演示工作台,npm run dev 即可开始绘制;同时导出 SeatMapEditor 组件与几何工具函数, 方便嵌入已有的 Vue 应用。

功能概览

区域绘制

  • 矩形、椭圆、多边形、直线、二次贝塞尔弧线和测距标注。
  • 拖拽整体移动,逐顶点、端点与弧线控制点微调;矩形与多边形可点选边并拖动控制点设置正负弯曲量。
  • 每个顶点可设为「棱角 / 圆滑」并调整切线影响范围;圆滑连接经过原顶点,不会截断两边。
  • 快捷键:选中边后用 [ / ] 微调弯曲量、0 恢复直线;选中顶点后用 1 切换棱角、2 切换圆滑。
  • 按住 Space 或 H 配合鼠标拖拽可临时平移,松开后自动回到选择工具。
  • 区域支持 Ctrl+D 复制、15° 步进旋转、锁定、尺寸显隐和对象层内前后顺序调整。

复合区域与孔洞

  • 左上角「区域工具 / 孔洞工具」互斥切换:区域模式只编辑独立区域,孔洞不可直接命中。
  • 选中闭合外区域后进入孔洞模式,可新增、平移、调整或删除该区域内部孔洞,并在左栏查看孔洞列表。
  • 矩形与圆形孔沿用四角加四边中点的八点缩放,自由孔逐顶点调整,拖动过程始终限制在父区域范围内。
  • 孔洞可拆回独立多边形或直接删除;主画布、座位画布、鹰眼与发布预览统一使用 evenodd 填充。

CAD 与 SVG 导入

  • 上传 ASCII DXF 自动识别毫米、厘米、米、英寸和英尺,按图层筛选,并把闭合 LWPOLYLINE/POLYLINE、 圆、椭圆、闭合样条、SOLID/3DFACE 转为可编辑区域;开放线、圆弧、文字、标注可作为参考对象导入。
  • 解析在 Web Worker 中执行,确认后整批只产生一条撤销记录。
  • 上传 SVG 解析基础图形、文字、分组、defs/use、viewBox、嵌套变换与文档内 CSS, 路径命令 M/L/H/V/C/S/Q/T/A/Z 会采样为可继续编辑的区域或参考线;同一 <path> 内的闭合子路径 按 evenodd 或 nonzero 自动识别为复合区域孔洞。
  • 脚本、外部引用、图片、裁剪、遮罩和滤镜会被阻止或给出兼容性提示;DWG、二进制 DXF、 HATCH/ACIS/代理对象会明确计入跳过统计。

座位绘制

  • 在画布拖出首排基准线再指定整体深度,自动生成规则座位矩阵;每个座位块用单个 Konva Shape 批量绘制, 座位数量不会等量增加场景节点。
  • 座距、排距、错位、弧高、过道宽度和座位尺寸均以米保存,按文档级 pixelsPerMeter 换算为画布坐标。
  • 支持「后排每排增减」生成前窄后宽或前宽后窄的梯形座位块,开启「居中变化」时增减都围绕首排中心对齐。
  • 编号支持数字、字母、方向、奇偶步长、蛇形、跨排连续和跳号;显式纵向/横向过道与座位缺口在重新生成时不会补回。
  • 座位块始终单选,可整体平移或围绕块中心按指定角度旋转校正,两种操作都只提交一条可撤销历史。
  • 排号竖条可通过 showRowLabels 开启,支持左右位置、米制宽度、边框与字号配置。
  • 单座可设置 0/90/180/270 四向旋转,座椅旋转时座位号保持正向。

票档与选座预览

  • 票档步骤支持价格与颜色管理、实时画笔预览、可见范围、清除、整排、框选、套索和平移; B/E/R/X/L 切换工具,1/3/5 切换画笔范围,空格或 H 临时平移。
  • 座位的 priceLevelId 是事实来源,区域主票档图作为可检测过期的缓存保存。
  • 选座预览支持场馆总览、区域视角和座位视角三级缩放;最大视角可配置为「直接座位」以锁定在座位层。
  • 座位绘制、票档和选座预览共用右上角鹰眼,可点击或拖动快速定位,也可收起为图标。
  • 发布步骤支持一期、二期及更多开放阶段,为每期选择区域与开放时段,导出的发布计划可按指定时间计算允许选座的区域。

舞台与幕布

  • 首次拖拽确定幕布宽度,创建后用两端点调整宽度;弧顶锁定在跨度正中且只调整弧高。
  • 渐变带从幕布向内弧前方过渡,两个前沿角点可独立拖动深度和横向收放形成梯形投影, 也可设置统一前景深度、双色渐变、透明度、文字与字号。

工程能力

  • 撤销、重做、自动保存、本地恢复与 JSON 导出,两步工作流共用同一份历史。
  • 新建场馆默认 20px = 1m,可在 0.1–1000px/m 范围内修改比例,换算保留小数以保证极端比例往返可逆。
  • 网格显示、交叉点吸附与 0.1–1000m 基础网格间距,缩小时按 1/2/5 × 10^n 自动合并。
  • 草稿以 schemaVersion 标识,加载时逐级迁移,兼容历史 seatSize / seatRadius 字段。

快速开始

需要 Node.js >= 20.19.0 与 npm。

git clone <仓库地址>
cd seatmap-editor
npm ci
npm run dev

默认地址:http://127.0.0.1:4181/

仓库已提交 package-lock.json,推荐用 npm ci 安装以获得可复现的依赖树。 根目录的 .npmrc 关闭了 peer 依赖自动解析,这是为了绕开 npm 在重建依赖树时 解析 vitest optional peer 会触发的 arborist 报错,原因写在 .npmrc 注释里。

常用脚本

命令 说明
npm run dev 启动演示工作台开发服务器
npm run build 构建待发布的库产物,输出到 dist/(等同 build:lib)
npm run build:lib 类型检查 → 库构建 → 生成 .d.ts 类型声明
npm run build:demo 构建静态演示站,输出到 dist-demo/
npm run preview 预览演示站构建产物
npm test 运行单元测试
npm run test:watch 监听模式运行单元测试
npm run typecheck vue-tsc 类型检查

作为组件接入

直接安装已发布的包,产物是编译好的 ESM 与类型声明,Webpack、Rollup、Vite 均可消费:

npm install seatmap-editor konva
import { SeatMapEditor } from 'seatmap-editor';
import 'seatmap-editor/style.css';

也可以按需引用几何与数据层工具,例如 regionHoleContainsPoint:

import { regionHoleContainsPoint } from 'seatmap-editor';

vue 是 peer 依赖,由宿主工程提供;konva、dxf-parser、@lucide/vue 会随本包自动安装。 组件自带全部样式,不依赖任何第三方 UI 组件库或 Tailwind CSS。 DXF 导入依赖 Web Worker,请确保构建工具支持 new Worker(new URL(...), { type: 'module' })。

在仓库内开发调试时,npm run build:lib 会重新生成 dist/;如需在消费端联调,可用 npm pack 产出 tarball 后安装,或让宿主工程通过 link: 指向本目录。

目录结构

src/
├── App.vue                 # 演示工作台:顶栏、画布、属性栏编排
├── index.ts                # 包入口(类型入口),导出组件、几何工具与数据模型
├── lib-entry.ts            # 库构建入口:聚合样式并转发 index 的公开 API
├── main.ts                 # 演示应用挂载入口
├── models.ts               # 区域、座位块、票档、发布计划等数据模型
├── geometry.ts             # 多边形与孔洞几何计算
├── seat-layout.ts          # 座位矩阵生成、梯形排布、编号与过道
├── price-level.ts          # 票档分配与校验
├── release-plan.ts         # 分阶段开放计划
├── region-tools.ts         # 区域工具状态机
├── projection-screen.ts    # 舞台幕布几何
├── grid.ts / color.ts      # 网格吸附与颜色换算
├── dxf-import.ts           # DXF 解析
├── svg-import.ts           # SVG 解析
├── preview.ts              # 选座预览视角与命中判定
├── components/             # 画布、工具栏与属性面板
│   └── ui/                 # 内置轻量 UI 原子组件(Button / Input / Slider 等)
├── composables/            # 编辑器状态、历史与草稿持久化
├── styles/                 # 内置组件基础样式
└── workers/                # DXF 解析 Worker

tests/                      # 单元测试(Vitest)
docs/                       # 详细设计说明书
scripts/                    # 构建辅助脚本

vite.config.ts              # 演示站构建配置(输出 dist-demo/)
vite.lib.config.ts          # npm 库构建配置(输出 dist/)
tsconfig.build.json         # 类型声明生成配置

坐标与数据约定

  • 长度一律以米存储,仅在渲染时按 pixelsPerMeter 换算为画布坐标,因此比例尺调整不会改变业务数据。
  • 座位块的座距、排距、过道宽度、缺口宽度和座位尺寸都是米制参数,不属于画布缩放语义。
  • 座位颜色由 priceLevelId 决定;区域主票档图只是可检测过期的缓存。
  • 草稿的 schemaVersion 一旦发布不应回改,新增字段需在 use-region-editor 中补迁移分支。
  • 本地演示草稿保存在 localStorage 的 seatmap-region-editor-v1 键下; 首次读取时会自动迁移早期的 ikuzo-region-editor-v1 草稿并清理旧键。

浏览器支持

面向支持 ES2020 与 Web Worker 模块加载的现代浏览器(Chrome / Edge / Firefox / Safari 最新两个大版本)。 移动端按编辑文档保存的视角规则展示选座预览。

设计文档

docs/ 下保留了实现过程中沉淀的设计说明书:

参与贡献

欢迎提交 Issue 与 PR,请先阅读 CONTRIBUTING.md。 变更记录见 CHANGELOG.md。

许可证

MIT

第三方资源

  • 座椅图标 src/assets/default-seat.svg 随仓库以 MIT 许可提供。
  • 图标集来自 lucide(ISC 许可)。
  • 画布渲染基于 Konva,DXF 解析基于 dxf-parser。

Related Packages

@nextcloud/image-editor

Vue 3 image editor component for Nextcloud apps

7,319 2
vue-konva-to-svg

Extend Konva's functionality to export stages as SVG. Enhance the quality of exp...

3,434 0
vue3-konva

Vue binding to canvas element via Konva framework

24,596 1,358
vue-image-editor

나의 첫 캔버스 이미지 편집기

2,915 5
@oh-just-another/diagram-vue

Vue 3 wrapper for the diagram editor — a thin component over the custom element.

0 9

Version History

Version Released Vue License
0.2.0 ^3.5.0 MIT