Files
mywebbuilder.js/README.md
wtz 1d58d40185 feat: add onChanged callback, Delete key support, drag offset fix
- Add onChanged(callback) API for tracking page changes
- Support Delete/Backspace key to delete selected component
- Fix drag offset issue when moving components
- Add unsaved changes tracking in editor demo
- Update README documentation
2026-03-29 13:01:53 +08:00

281 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WebBuilder.js
IoT 可视化编辑器库 - 基于网格布局的拖拽式页面构建器
中文 | [English](README_EN.md)
## 特性
- 📱 固定手机比例画布375×812
- 📐 网格布局,单元格 1:1 正方形
- 🖱️ 拖拽添加、移动组件
- ⌨️ Delete/Backspace键删除选中组件
- ⚙️ 属性面板,实时预览
- 💾 JSONB 格式保存/加载
- 🎨 自定义组件支持
- 🔔 变化回调通知
## 项目结构
```
.
├── js/lib/webbuilder/ # 核心库(你需要引入的)
│ ├── webbuilder.js # 主文件
│ └── types/ # 内部模块
├── editor.html # 示例编辑器
├── js/editor/editor.js # 示例编辑器逻辑
├── css/editor.css # 示例编辑器样式
├── README.md # 中文文档
└── README_EN.md # English
```
> **注意**: `editor.html` 和 `js/editor/` 是示例代码,展示如何使用本库。
> 实际使用时只需引入 `js/lib/webbuilder/webbuilder.js`,然后自行实现编辑器逻辑。
## 快速开始
### 1. 引入文件
```html
<script src="js/lib/webbuilder/webbuilder.js"></script>
```
### 2. 创建容器
```html
<div id="editor" style="width: 100%; height: 600px;"></div>
```
### 3. 初始化编辑器
```javascript
webbuilder.init('#editor');
```
### 4. 注册组件
```javascript
webbuilder.define('gauge', {
type: 'gauge',
label: '仪表盘',
icon: '📊',
defaultColumnSpan: 6,
defaultRowSpan: 6,
defaultProps: {
label: '温度',
value: 25,
unit: '°C'
},
traits: [
{ type: 'text', name: 'label', label: '标签' },
{ type: 'number', name: 'value', label: '值' },
{ type: 'text', name: 'unit', label: '单位' }
],
render: function(props) {
var el = document.createElement('div');
el.className = 'my-gauge';
el.innerHTML = '<div class="value">' + props.value + props.unit + '</div>' +
'<div class="label">' + props.label + '</div>';
return el;
}
});
```
## API 文档
### 初始化
```javascript
webbuilder.init(containerSelector)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| containerSelector | string/HTMLElement | 容器选择器或元素 |
### 注册组件
```javascript
webbuilder.define(name, definition)
```
| 参数 | 类型 | 说明 |
|------|------|------|
| name | string | 组件唯一标识 |
| definition | object | 组件定义对象 |
**definition 结构:**
```javascript
{
type: 'component-type', // 组件类型
label: '组件名称', // 显示名称
icon: '📊', // 工具箱图标
defaultColumnSpan: 6, // 默认跨列数
defaultRowSpan: 4, // 默认跨行数
defaultProps: { ... }, // 默认属性
traits: [ ... ], // 属性定义(用于属性面板)
render: function(props) { ... } // 渲染函数,返回 DOM 元素
}
```
### 注册变化回调
```javascript
webbuilder.onChanged(function(action, data) {
// action: 'add' | 'delete' | 'move' | 'update' | 'load' | 'clear'
// data: 相关数据组件实例、组件ID等
});
```
| action | 说明 | data |
|--------|------|------|
| add | 添加组件 | 组件实例对象 |
| delete | 删除组件 | { id: 组件ID } |
| move | 移动组件 | 组件实例对象 |
| update | 属性面板修改属性 | 组件实例对象 |
| load | 加载JSONB | { count: 组件数量 } |
| clear | 清空画布 | null |
### 导出 JSONB
```javascript
var jsonb = webbuilder.toJSONB();
```
返回格式:
```javascript
{
version: '1.0',
layouts: {
phone: {
canvas: {
width: 375,
height: 812,
columns: 24,
cellSize: 13.5,
rows: 52,
gap: 2,
background: '#f5f5f5'
},
components: [
{
id: 'gauge-1',
type: 'gauge',
grid: {
startCell: 0,
colSpan: 6,
rowSpan: 6
},
props: { ... }
}
]
},
computer: null
}
}
```
### 加载 JSONB
```javascript
webbuilder.fromJSONB(jsonb);
```
### 渲染到容器
```javascript
var components = webbuilder.renderToDiv(container);
```
返回组件列表:
```javascript
[
{
element: HTMLElement, // 组件 DOM 元素
wrapper: HTMLElement, // 包装容器
props: { ... }, // 组件属性(深拷贝)
id: 'gauge-1',
type: 'gauge'
}
]
```
### 其他方法
```javascript
// 获取画布配置
webbuilder.getCanvasConfig();
// 获取所有组件
webbuilder.getComponents();
// 清空画布
webbuilder.clear();
```
## 组件定义规范
### traits 属性定义
用于生成属性面板:
```javascript
traits: [
{ type: 'text', name: 'label', label: '标签', default: '' },
{ type: 'number', name: 'value', label: '值', default: 0 },
{ type: 'checkbox', name: 'state', label: '状态', default: false }
]
```
| type | 说明 |
|------|------|
| text | 文本输入框 |
| number | 数字输入框 |
| checkbox | 复选框 |
### render 函数
必须返回 DOM 元素:
```javascript
render: function(props) {
var el = document.createElement('div');
el.textContent = props.label;
return el;
}
```
## 网格系统
- **画布宽度**375px固定
- **列数**24列
- **单元格大小**:约 13.5px × 13.5px(正方形)
- **组件位置**:通过 `startCell`(起始格子编号)+ `colSpan`(跨列数)+ `rowSpan`(跨行数)定义
格子编号从 0 开始,按行递增:
```
0 1 2 3 ... 23
24 25 26 27 ... 47
48 49 50 51 ... 71
...
```
## 浏览器兼容性
- Chrome 60+
- Firefox 55+
- Safari 11+
- Edge 79+
## 许可证
MIT
---
*参考项目:[webbuilder.js](https://github.com/qrailibs/webbuilder.js)*