wl-draw 是一个功能完善的数字白板应用,支持多种绘图工具、文本编辑、画布操作等功能。应用采用插件化架构设计,核心系统保持简洁稳定,功能通过插件扩展,具有高度的灵活性和可维护性。
- 🎨 绘图工具:选择、平移、矩形、圆形、直线、箭头、画笔、文本、图片
- 🖼️ 画布操作:缩放(鼠标滚轮、按钮)、平移(工具和空格键)、无限画布
- 📦 对象管理:对象添加、删除、选择、移动、缩放、对齐和吸附
- 📜 历史记录:撤销/重做功能,支持最多 50 步历史记录
- 💾 导出功能:支持导出为图片(PNG)和 JSON 格式
- ⌨️ 快捷键支持:所有工具支持键盘快捷键,支持快捷键冲突检测和规范化处理
- 🔌 插件化架构:完整的工具插件系统,支持工具注册、生命周期管理、事件系统、Hook 系统、快捷键管理、依赖管理和懒加载
- Node.js: >= 18.0.0
- pnpm: >= 8.0.0
# 克隆项目
git clone <repository-url>
cd wl-draw
# 安装依赖
pnpm install# 启动开发服务器
pnpm dev应用将在 http://localhost:5173 启动。
# 构建生产版本
pnpm build
# 预览生产构建
pnpm preview# 检查代码
pnpm lint:check
# 格式化代码
pnpm format
# 自动修复并格式化
pnpm check- 选择工具:点击工具栏中的选择工具(快捷键
V)或使用快捷键切换 - 绘制图形:选择绘图工具(矩形、圆形、直线等),在画布上拖拽绘制
- 编辑对象:使用选择工具选中对象后,可以移动、缩放、删除
- 文本编辑:选择文本工具(快捷键
T),在画布上点击添加文本 - 画布操作:
- 使用鼠标滚轮缩放画布
- 按住空格键拖拽平移画布
- 使用工具栏的缩放按钮
| 功能 | 快捷键 |
|---|---|
| 选择工具 | V |
| 矩形工具 | R |
| 圆形工具 | C |
| 直线工具 | L |
| 箭头工具 | A |
| 画笔工具 | P |
| 文本工具 | T |
| 导出图片 | Shift+E |
| 导出 JSON | Shift+J |
| 撤销 | Ctrl+Z |
| 重做 | Ctrl+Shift+Z |
| 放大 | Ctrl+= |
| 缩小 | Ctrl+- |
wl-draw/
├── public/ # 静态资源
│ └── logo.webp # 项目 Logo
├── src/
│ ├── components/ # Vue 组件
│ │ ├── Canvas.vue # 画布组件
│ │ ├── Toolbar.vue # 工具栏组件
│ │ └── ...
│ ├── composables/ # 组合式函数
│ │ ├── events/ # 事件处理
│ │ ├── features/ # 功能封装
│ │ ├── state/ # 状态管理
│ │ └── tool/ # 工具相关
│ ├── config/ # 配置文件
│ │ ├── canvas.ts # 画布配置
│ │ ├── export.ts # 导出配置
│ │ └── theme.ts # 主题配置
│ ├── constants/ # 常量定义
│ ├── plugins/ # 插件系统
│ │ ├── builtin/ # 内置插件
│ │ ├── composables/ # 插件组合函数
│ │ ├── registry.ts # 插件注册表
│ │ ├── events.ts # 事件系统
│ │ └── types.ts # 插件类型定义
│ ├── stores/ # Pinia 状态管理
│ │ ├── canvas.ts # 画布状态
│ │ └── history.ts # 历史记录状态
│ ├── types/ # TypeScript 类型定义
│ ├── utils/ # 工具函数
│ ├── App.vue # 根组件
│ └── main.ts # 入口文件
├── docs/ # 文档目录
│ ├── 插件化架构评分报告.md
│ └── 插件开发指南.md
├── package.json # 项目配置
└── README.md # 项目说明
- Vue 3 - 渐进式 JavaScript 框架
- TypeScript - 类型安全的 JavaScript 超集
- Vite - 下一代前端构建工具
- Leafer UI - 高性能 Canvas 渲染引擎
- @leafer-in/editor - 对象编辑功能(选择、移动、缩放)
- @leafer-in/viewport - 视口和缩放功能
- @leafer-in/view - 视图功能
- @leafer-in/arrow - 箭头绘制功能
- @leafer-in/text-editor - 文本编辑功能
- @leafer-in/export - 画布导出功能
- leafer-x-easy-snap - 对象对齐和吸附功能
- Pinia - Vue 官方状态管理库
- Naive UI - Vue 3 组件库
- Tailwind CSS - 实用优先的 CSS 框架
- VueUse - Vue Composition API 工具集合
- Biome - 快速、可靠的代码检查和格式化工具
- Husky - Git hooks 工具
- lint-staged - 对暂存文件运行 linter
- commitlint - Git 提交信息规范检查工具
- unplugin-auto-import - 自动导入 API,无需手动 import
- unplugin-vue-components - 自动导入 Vue 组件
- unplugin-icons - 按需图标导入,基于 Iconify
- @iconify/json - Iconify 图标数据集合
- rolldown-vite - 基于 Rolldown 的高性能 Vite 构建工具
wl-draw 采用微内核插件化架构,遵循以下核心原则:
- 微内核:核心系统保持最小化和稳定,仅包含基础功能和插件管理机制
- 功能模块化:业务功能以插件形式存在,每个插件负责独立功能
- 职责清晰:核心系统管理插件生命周期,插件实现具体功能
- ToolPlugin 接口:定义插件必须实现的统一接口
- 插件元数据:包含版本、描述、依赖等信息
- 能力声明:通过
capabilities声明插件行为,系统自动调整 - 工具实例:插件通过
createTool创建工具实例,实现具体功能
- 插件注册表(PluginRegistry):统一管理所有插件的注册、查询、卸载
- 插件验证:注册时验证插件规范、依赖关系、版本兼容性
- 生命周期管理:支持插件安装、激活、停用、卸载等生命周期
- 插件状态跟踪:跟踪插件状态(registered、activated、deactivated、error),记录注册和激活时间
- 懒加载支持:支持插件懒加载,按需加载插件代码,提升初始加载性能
- 依赖管理:
- 支持插件依赖声明和依赖顺序计算
- 使用拓扑排序算法确保依赖顺序正确
- 自动检测循环依赖并抛出错误
- 自动加载依赖插件
- 事件驱动:基于事件总线的插件间通信机制
- 类型安全:事件系统提供完整的 TypeScript 类型支持
- 事件管理:
- 自动跟踪事件订阅,插件卸载时自动清理
- 支持一次性事件订阅(once)
- 事件处理器错误自动捕获和处理
- 事件类型:支持丰富的事件类型,包括:
- 插件生命周期事件(激活、停用)
- 工具切换事件
- 对象操作事件(创建、删除、选择、修改)
- 画布操作事件(缩放、平移)
- 绘制事件(开始、更新、完成)
- 快捷键触发事件
- 生命周期钩子:在关键节点(工具切换、绘制开始/完成)执行自定义逻辑
- 拦截器钩子:支持在操作前拦截(如阻止工具切换)
- 处理器钩子:支持在操作后执行后续处理
插件通过 capabilities 声明能力,系统根据能力自动:
- 切换画布模式(绘图模式/普通模式)
- 分发事件(拖拽、点击等)
- 启用/禁用功能(如拖拽平移)
- 快捷键注册:插件可以通过
shortcut字段声明快捷键 - 快捷键规范化:自动规范化快捷键格式(统一大小写、排序修饰键)
- 冲突检测:注册时自动检测快捷键冲突,并发出警告
- 快捷键解析:支持解析复杂快捷键组合(Ctrl、Shift、Alt、Meta)
- 事件触发:快捷键触发时自动发送
shortcut:triggered事件
┌─────────────────────────────────────┐
│ UI 层 (Vue Components) │
│ Toolbar, Canvas, ToolSelector... │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 核心系统 (Core System) │
│ - 插件注册表 (PluginRegistry) │
│ - 事件总线 (EventBus) │
│ - Hook 系统 (Hook System) │
│ - 工具管理器 (Tool Manager) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 插件层 (Plugin Layer) │
│ - 内置插件 (Builtin Plugins) │
│ - 工具插件 (Tool Plugins) │
│ - 扩展插件 (Extension Plugins) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 基础设施层 (Infrastructure) │
│ - Leafer UI (绘图引擎) │
│ - Pinia (状态管理) │
│ - VueUse (工具库) │
└─────────────────────────────────────┘
- 插件系统 (
src/plugins/):插件注册、管理、事件、Hook、快捷键 - 状态管理 (
src/stores/):画布状态、工具状态、对象管理、历史记录 - 工具组合函数 (
src/composables/):工具逻辑封装和复用 - 组件 (
src/components/):UI 组件(工具栏、画布、工具选择器等) - 配置 (
src/config/):画布配置、主题配置、导出配置 - 错误处理 (
src/utils/errorHandler.ts):统一的错误处理机制,支持错误分类、日志记录和用户友好的错误提示
应用内置了以下插件,按类别分类:
- 选择工具 (
select) - 快捷键:V- 选择和操作画布对象 - 平移工具 (
pan) - 平移画布视图
- 矩形工具 (
rect) - 快捷键:R- 绘制矩形 - 圆形工具 (
circle) - 快捷键:C- 绘制圆形 - 直线工具 (
line) - 快捷键:L- 绘制直线 - 箭头工具 (
arrow) - 快捷键:A- 绘制箭头 - 画笔工具 (
pen) - 快捷键:P- 自由手绘 - 文本工具 (
text) - 快捷键:T- 添加文本 - 图片工具 (
image) - 添加图片到画布
- 导出图片 (
export) - 快捷键:Shift+E- 导出画布为图片 - 导出 JSON (
exportJson) - 快捷键:Shift+J- 导出画布为 JSON - 撤销 (
undo) - 快捷键:Ctrl+Z- 撤销上一步操作 - 重做 (
redo) - 快捷键:Ctrl+Shift+Z- 重做上一步操作 - 放大 (
zoomIn) - 快捷键:Ctrl+=- 放大画布 - 缩小 (
zoomOut) - 快捷键:Ctrl+-- 缩小画布
所有插件支持懒加载,提升应用初始加载性能。
插件开发遵循统一的接口规范,支持三种插件类别:
- 选择工具 (
selection):实现对象选择和操作功能(如选择工具、平移工具) - 绘图工具 (
drawing):实现绘图功能(如矩形、圆形、画笔、文本等) - 实用工具 (
utility):实现辅助功能(如导出、撤销/重做、缩放等)
插件可以声明依赖关系、注册生命周期钩子、订阅事件、声明快捷键,并支持懒加载以优化性能。
详细的插件开发指南请参考 插件开发指南。
项目使用以下工具保证代码质量:
- Biome: 代码检查和格式化
- Husky: Git hooks 管理
- lint-staged: 暂存文件检查
- commitlint: 提交信息规范检查
项目遵循 Conventional Commits 规范:
<type>(<scope>): <subject>
<body>
<footer>
类型(type):
feat: 新功能fix: 修复问题docs: 文档更新style: 代码格式调整refactor: 代码重构perf: 性能优化test: 测试相关chore: 构建/工具链相关
- 在
src/plugins/builtin/目录下创建插件文件 - 实现
ToolPlugin接口 - 在
src/plugins/builtin/index.ts中注册插件
import type { ToolPlugin } from '../types'
export const myPlugin: ToolPlugin = {
id: 'my-plugin',
name: '我的插件',
category: 'utility',
version: '1.0.0',
shortcut: 'Ctrl+M',
capabilities: {
requiresDrawingMode: false,
},
createTool() {
return {
onActivate() {
console.log('插件已激活')
},
onDeactivate() {
console.log('插件已停用')
},
}
},
}更多详细信息请参考 插件开发指南。
本项目采用 MIT 许可证。详情请参阅 LICENSE 文件。
Made with ❤️ using Vue 3 and Leafer UI
