CNCjs小挂件开发教程:如何创建自定义数控界面
CNCjs是一款强大的Web-based数控界面,支持Grbl、Marlin、Smoothieware和TinyG控制器。通过开发自定义小挂件(widget),用户可以根据自己的需求定制数控操作界面,提升工作效率。本教程将带你从零开始创建属于自己的CNCjs小挂件,无需复杂编程知识,只需按照步骤操作即可完成!
小挂件开发准备工作 🛠️
在开始开发前,请确保你的开发环境已满足以下条件:
- 安装Node.js:CNCjs基于Node.js开发,需先安装Node.js(建议v14+版本)
- 获取CNCjs源码:
git clone https://gitcode.com/gh_mirrors/cn/cncjs cd cncjs npm install - 熟悉项目结构:小挂件主要存放在
src/app/widgets/目录下,每个小挂件通常包含:- JSX组件文件(.jsx)
- 样式文件(.styl)
- 配置文件
CNCjs默认界面展示了多种小挂件,包括Axes、Visualizer、Console等
小挂件开发核心概念 🔑
1. WidgetConfig类
所有小挂件都通过WidgetConfig类管理配置数据,位于src/app/widgets/WidgetConfig.js。它提供了简单的键值对存储接口:
// 初始化配置
const config = new WidgetConfig('my-widget-id');
// 读取配置
const value = config.get('key', 'default-value');
// 保存配置
config.set('key', 'new-value');
2. 小挂件目录结构
一个标准的小挂件目录结构如下:
src/app/widgets/MyWidget/
├── index.jsx # 主组件
├── index.styl # 样式文件
├── components/ # 子组件
└── constants.js # 常量定义
3. 状态管理与控制器交互
小挂件通过controller对象与CNC控制器交互,支持发送G代码、监听状态变化等:
// 发送G代码
controller.command('gcode', 'G0 X100 Y100');
// 监听控制器状态变化
controller.addListener('controller:state', (type, state) => {
console.log('控制器状态更新:', type, state);
});
从零创建自定义小挂件 🚀
步骤1:创建基础文件结构
首先在src/app/widgets/目录下创建你的小挂件目录:
mkdir -p src/app/widgets/MyWidget
touch src/app/widgets/MyWidget/index.jsx
touch src/app/widgets/MyWidget/index.styl
步骤2:编写基础组件代码
编辑src/app/widgets/MyWidget/index.jsx:
import React, { PureComponent } from 'react';
import Widget from 'app/components/Widget';
import WidgetConfig from '../WidgetConfig';
import styles from './index.styl';
class MyWidget extends PureComponent {
static propTypes = {
widgetId: PropTypes.string.isRequired
};
config = new WidgetConfig(this.props.widgetId);
state = {
// 初始化状态
message: this.config.get('message', 'Hello CNCjs!')
};
componentDidMount() {
// 组件挂载时执行
console.log('MyWidget mounted!');
}
render() {
return (
<Widget>
<Widget.Header>
<Widget.Title>我的自定义小挂件</Widget.Title>
</Widget.Header>
<Widget.Content className={styles.content}>
<h3>{this.state.message}</h3>
<p>这是一个简单的CNCjs小挂件示例</p>
</Widget.Content>
</Widget>
);
}
}
export default MyWidget;
步骤3:添加样式
编辑src/app/widgets/MyWidget/index.styl:
.content
padding: 16px
text-align: center
h3
color: #333
margin-bottom: 8px
p
color: #666
font-size: 0.9rem
步骤4:注册小挂件
要让CNCjs识别新的小挂件,需要在src/app/widgets/index.js中添加注册代码:
// 导入你的小挂件
import MyWidget from './MyWidget';
// 在widgets对象中添加
export default {
// ...其他小挂件
'my-widget': MyWidget, // 键名会作为小挂件ID
};
步骤5:测试小挂件
启动开发服务器测试你的小挂件:
npm run dev
访问http://localhost:8000,在CNCjs界面中添加你的小挂件:
- 点击右上角"+"按钮
- 在小挂件列表中选择"我的自定义小挂件"
- 拖放调整位置
高级功能实现 💡
1. 添加配置界面
为小挂件添加配置功能,让用户可以自定义参数:
// 在MyWidget组件中添加配置模态框
openSettings = () => {
this.setState({ showSettings: true });
};
saveSettings = (newMessage) => {
this.config.set('message', newMessage);
this.setState({ message: newMessage, showSettings: false });
};
// 在render方法中添加配置按钮和模态框
<Widget.Controls>
<Widget.Button onClick={this.openSettings}>
<i className="fa fa-cog" />
</Widget.Button>
</Widget.Controls>
{this.state.showSettings && (
<Modal onClose={this.closeSettings}>
<Modal.Header>
<Modal.Title>设置</Modal.Title>
</Modal.Header>
<Modal.Body>
<input
type="text"
value={this.state.message}
onChange={(e) => this.setState({ tempMessage: e.target.value })}
/>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.saveSettings}>保存</Button>
</Modal.Footer>
</Modal>
)}
2. 与控制器交互
添加G代码发送功能,让小挂件可以控制机床:
sendGCode = () => {
const gcode = 'G0 X0 Y0 Z0'; // 回零
controller.command('gcode', gcode, (err) => {
if (err) {
console.error('发送G代码失败:', err);
} else {
console.log('G代码发送成功');
}
});
};
// 在render中添加按钮
<Button onClick={this.sendGCode}>回零</Button>
3. 3D可视化集成
如果需要实现类似Visualizer的3D功能,可以参考src/app/widgets/Visualizer/目录下的代码,使用Three.js实现3D渲染:
import * as THREE from 'three';
componentDidMount() {
// 初始化Three.js场景
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
this.renderer = new THREE.WebGLRenderer();
this.element.appendChild(this.renderer.domElement);
// 添加物体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
this.cube = new THREE.Mesh(geometry, material);
this.scene.add(this.cube);
this.camera.position.z = 5;
this.animate();
}
animate = () => {
requestAnimationFrame(this.animate);
this.cube.rotation.x += 0.01;
this.cube.rotation.y += 0.01;
this.renderer.render(this.scene, this.camera);
};
小挂件打包与分享 📦
完成开发后,可以将你的小挂件打包分享给其他CNCjs用户:
-
打包小挂件:
npm run build -
分享方式:
- 将
src/app/widgets/MyWidget/目录压缩为ZIP文件 - 提供安装说明,指导用户将文件复制到CNCjs的widgets目录
- 将
-
发布到社区:
- 可以将你的小挂件发布到CNCjs社区论坛或GitHub,帮助更多用户
常见问题与解决方案 ❓
Q: 小挂件不显示怎么办?
A: 检查以下几点:
- 确保小挂件已在
src/app/widgets/index.js中注册 - 检查浏览器控制台是否有错误信息
- 确认组件名称和文件路径是否正确
Q: 如何调试小挂件?
A: 使用Chrome开发者工具:
- 按F12打开开发者工具
- 在Sources面板中找到你的小挂件代码
- 设置断点进行调试
Q: 小挂件如何保存用户配置?
A: 使用WidgetConfig类的set和get方法,配置会自动保存到本地存储
总结
通过本教程,你已经了解了CNCjs小挂件的开发流程和核心概念。从基础的"Hello World"小挂件,到实现与控制器交互和3D可视化,你可以根据自己的需求扩展更多功能。CNCjs的模块化设计让定制界面变得简单,希望你能开发出实用的小挂件,提升数控加工体验!
如果你开发了有趣的小挂件,欢迎在CNCjs社区分享你的作品,让更多人受益于你的创意!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





