- 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
6.1 KiB
6.1 KiB
WebBuilder.js
IoT 可视化编辑器库 - 基于网格布局的拖拽式页面构建器
中文 | English
特性
- 📱 固定手机比例画布(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. 引入文件
<script src="js/lib/webbuilder/webbuilder.js"></script>
2. 创建容器
<div id="editor" style="width: 100%; height: 600px;"></div>
3. 初始化编辑器
webbuilder.init('#editor');
4. 注册组件
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 文档
初始化
webbuilder.init(containerSelector)
| 参数 | 类型 | 说明 |
|---|---|---|
| containerSelector | string/HTMLElement | 容器选择器或元素 |
注册组件
webbuilder.define(name, definition)
| 参数 | 类型 | 说明 |
|---|---|---|
| name | string | 组件唯一标识 |
| definition | object | 组件定义对象 |
definition 结构:
{
type: 'component-type', // 组件类型
label: '组件名称', // 显示名称
icon: '📊', // 工具箱图标
defaultColumnSpan: 6, // 默认跨列数
defaultRowSpan: 4, // 默认跨行数
defaultProps: { ... }, // 默认属性
traits: [ ... ], // 属性定义(用于属性面板)
render: function(props) { ... } // 渲染函数,返回 DOM 元素
}
注册变化回调
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
var jsonb = webbuilder.toJSONB();
返回格式:
{
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
webbuilder.fromJSONB(jsonb);
渲染到容器
var components = webbuilder.renderToDiv(container);
返回组件列表:
[
{
element: HTMLElement, // 组件 DOM 元素
wrapper: HTMLElement, // 包装容器
props: { ... }, // 组件属性(深拷贝)
id: 'gauge-1',
type: 'gauge'
}
]
其他方法
// 获取画布配置
webbuilder.getCanvasConfig();
// 获取所有组件
webbuilder.getComponents();
// 清空画布
webbuilder.clear();
组件定义规范
traits 属性定义
用于生成属性面板:
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 元素:
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