HMI 设计器 (GrapesJS)
Darra IDE 的 HMI 设计器基于开源 GrapesJS 0.21 拖拽引擎构建, 将 HTML + CSS + JavaScript 工作流可视化, 避免工程师手写标签坐标。设计器支持两种编辑模式: FreeForm (拖拽) 和 Code (纯代码), 可随时互转。
启动设计器
- IDE 左侧 "HMI 设计" 节点 → 右键 → "新建 HMI 页面"
- 弹出 "新建页面" 对话框: 页面名称 / 路由 / 是否首页
- 双击节点打开设计器, 默认进入 FreeForm 模式
或通过菜单 HMI → 新建 LocalHMI 项目 / 新建 WebHMI 项目, 项目内可挂多个页面。
工作区布局
+------------------------------------------------------------+
| 顶部工具栏 | 设备尺寸切换 / 撤销 / 重做 / 预览 / 保存 |
+------+---------------------------------+-------------------+
| | | |
| 左 | 画布 (Canvas) | 右侧属性面板 |
| 侧 | 1920 x 1080 @ 缩放 60% | |
| Block| + 吸附网格 10px | Style Traits |
| 面板 | + 参考线 | 图层 (Layers) |
| | | |
+------+---------------------------------+-------------------+
| 底部: 设备预览 / 命令行 / 导入 HTML |
+------------------------------------------------------------+
画布 (Canvas)
- 尺寸由
HMIProjectDef.Settings.DesignWidth/Height决定 (默认 1920 × 1080, 16:9) ScaleMode有三种:FitRatio— 按比例缩放 (保留宽高比, 黑边填充), 推荐Stretch— 拉伸填满 (可能变形)Fixed— 固定像素 (出现滚动条)
- 网格吸附: 默认 10px, 顶部工具栏可切
1 / 5 / 10 / 20 - 参考线: 拖动控件时自动出现橙色对齐线, 按住 Alt 禁用吸附
Block 面板 (左侧)
Block = 可拖入画布的预制控件。分类自动从 darra-controls.js 和 darra-devextreme.js 读取:
| 分类 | Block 数量 | 举例 |
|---|---|---|
| 基础控件 | 5 | button / led / numeric / input / label |
| 图表控件 | 5 | gauge / trend / chart / progress-bar / slider |
| 工业控件 | 4 | tank / pipe / motor / valve |
| 系统控件 | 4 | alarm-list / image-toggle / nav-button / panel |
| 运动控制 | 3 | axis / jog-panel / motion-path |
| 机器人 | 3 | robot-status / robot-jog / robot-3d |
| 视觉检测 | 2 | camera-view / vision-result |
| 边缘网关 | 3 | comm-status / device-list / data-logger |
| 用户管理 | 3 | login-panel / user-badge / permission-gate |
| 布局 | 3 | separator / tab-container / group-box |
| DevExtreme | 10 | dx-grid / dx-tree / dx-scheduler / dx-pivot / dx-form / dx-speedometer / dx-linear-gauge / dx-bar-gauge / dx-bullet / dx-sparkline |
拖入画布后会生成对应 <darra-*> 标签。
Trait 属性面板 (右侧 Traits 标签)
选中画布上某个控件, 右侧自动显示该控件注册的 Trait 列表。以 <darra-numeric> 为例:
| Trait 名 | HTML 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
| 变量 | var | text | "" | PLC 变量 (DB1.Temp / MW100) |
| 格式 | format | text | 0.00 | 小数点后位数 |
| 单位 | unit | text | "" | 显示后缀 |
| 字号 | font-size | text | 32px | 覆盖 CSS |
| 颜色 | color | color | #333 | 文本颜色 |
修改 Trait 会立即反映到画布 HTML 标签上:
<darra-numeric var="DB1.T" format="0.00" unit="℃"></darra-numeric>
Style 面板 (CSS)
与普通 HTML 一致: display / position / width / height / margin / padding / font / background / border / box-shadow / transform。
所有样式会进入 HMIPageDef.CssCode 字段。可以直接点 + Add Property 写任意 CSS。
图层面板 (Layers)
树形显示 DOM 层次, 支持:
- 点击选中 (同步到画布高亮)
- 拖拽调整层叠 (
z-index或 DOM 顺序) - 右键: 复制 / 删除 / 锁定 / 隐藏
- 组 (Group): 选中多个 → 右键 → "组合", 作为
<darra-panel>容器
设备尺寸切换
顶部工具栏提供设备预览按钮 (Desktop / Tablet / Mobile), 用来验证响应式样式。注意: 切换后画布宽度变, 并不修改 DesignWidth, 只是调整 CSS @media 预览。
保存 & 存储模型
保存时, 设计器会把 GrapesJS 内部模型序列化到 HMIPageDef:
{
"Name": "反应釜",
"Route": "/reactor",
"IsHome": false,
"HtmlCode": "<div class=\"page\"><darra-led var=\"M0.0\"></darra-led></div>",
"CssCode": ".page { padding: 20px; }",
"JsCode": "// 用户自定义脚本",
"Elements": [
{
"Id": "el_001",
"Type": "Led",
"X": 100, "Y": 50, "Width": 40, "Height": 40,
"VariableBinding": "M0.0",
"ZIndex": 10,
"Properties": { "color-on": "#00FF00", "color-off": "#666" }
}
]
}
HtmlCode / CssCode / JsCode是最终渲染版本 (LocalHMI 直接用)Elements[]是IDE 编辑版本 (下次打开设计器还原画布, 保留控件的结构化信息)- 两者冗余存储但必须同步更新 — 设计器保存时自动回写
预览
- 快速预览: 顶部工具栏
预览按钮 → 新标签打开/local/<route>?preview=1(需 Service 已启动) - 真机预览:
F5 → 启动 HMI Runtime, LocalHMI 外壳全屏加载 - 外部预览: 浏览器访问
http://<PC 本机 IP>:18823/web/<route>
导入现有 HTML
顶部工具栏 导入 → 粘贴 HTML 代码块 (可带 <darra-*> 标签), GrapesJS 会解析并填充画布。适合从模板改写:
<darra-tank var="DB1.Level" max="100"></darra-tank>
<darra-pipe from="tank1" to="tank2" flow-var="DB1.Flow"></darra-pipe>
快捷键
| 快捷键 | 功能 |
|---|---|
| Ctrl+Z / Ctrl+Y | 撤销 / 重做 |
| Ctrl+C / Ctrl+V | 复制 / 粘贴控件 |
| Del | 删除选中 |
| Ctrl+S | 保存到 HMIPageDef |
| Ctrl+D | 复制到右下方 |
| Arrow | 按 1px 移动 (按住 Shift 10px) |
| Ctrl+E | 切换 FreeForm ↔ Code |
| F11 | 全屏预览 |
常见问题
| 问题 | 原因 | 解决 |
|---|---|---|
| 拖入控件后画布空白 | 控件 JS 未注入 | 检查 HmiWebServer 启动, /static/darra-controls.js 返回 200 |
| Trait 修改不生效 | 浏览器缓存 | 预览窗口按 Ctrl+F5 强刷 |
| 保存后丢失样式 | CssCode 被外部样式覆盖 | 去 ActiveSkin 看皮肤 CSS 变量是否冲突 |
| 切换 Code 模式后回不来 | 手写 HTML 非 GrapesJS 可解析结构 | 在 Code 模式内保存后可继续 Code 编辑, 不强制回拖拽 |
| 画布显示"未检测到 Service" | HmiWebServer 未启动 | 菜单 运行 → 启动 PLC Service, 等待 18823 端口监听 |
设计器内部架构 (只读参考)
Darra_Software_PLC/Darra_PLC_IDE_NEW/HMI/Designer/
HMI设计器.xaml.cs // IDE 容器 (内嵌 WebView2)
HMI页面定义.cs // 简化模型 (与 HMIModels.cs 互转)
GrapesJS 运行在 IDE 内嵌的 WebView2 实例里, 通过 postMessage 与 C# 交互:
IDE (C#) ─ host-object ─ WebView2 ─ GrapesJS JS
↑ ↓
┴──── JSON (HMIPageDef 序列化) ────┘