仪表盘组件 - Electron for 鸿蒙PC项目实战案例
本项目是一个基于Electron框架开发的仪表盘组件应用,为鸿蒙PC平台提供直观的仪表盘可视化功能。这是Electron初学者学习仪表盘可视化的理想示例,展示了如何使用Canvas API实现交互式仪表盘。

项目概述
本项目是一个基于Electron框架开发的仪表盘组件应用,为鸿蒙PC平台提供直观的仪表盘可视化功能。这是Electron初学者学习仪表盘可视化的理想示例,展示了如何使用Canvas API实现交互式仪表盘。
功能特点
- 仪表盘渲染:使用Canvas API绘制精美的仪表盘
- 数值展示:支持实时数值显示和动画过渡效果
- 交互功能:支持鼠标拖拽调整数值、点击设置等交互操作
- 颜色渐变:内置颜色渐变方案,根据数值范围显示不同颜色
- 多指针支持:支持单个或多个指针同时显示
- 自定义配置:支持自定义角度范围、刻度、标签等
- 响应式设计:适配不同窗口大小的界面布局
- 鸿蒙PC适配:针对鸿蒙PC平台优化的用户体验
技术架构
核心架构
- 主进程 (Main Process):由
main.js实现,负责应用程序生命周期管理和窗口创建 - 渲染进程 (Renderer Process):由
renderer.js实现,负责仪表盘渲染和用户交互 - 预加载脚本 (Preload Script):由
preload.js实现,提供安全的进程间通信桥接
文件结构
96-gauge-chart/
├── main.js # 主进程文件,应用入口
├── preload.js # 预加载脚本,进程通信
├── index.html # 应用界面
├── style.css # 样式文件
├── renderer.js # 渲染进程逻辑
└── README.md # 项目说明文档
核心代码解析
主进程 (main.js)
主进程负责创建和管理应用窗口,处理文件系统操作:
const { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
// 创建浏览器窗口并配置安全选项
const win = new BrowserWindow({
width: 800,
height: 600,
title: '仪表盘组件 - Electron for 鸿蒙PC项目实战案例',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
sandbox: true
}
});
win.loadFile('index.html');
}
// 应用生命周期管理
app.whenReady().then(() => {
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
渲染进程 (renderer.js)
渲染进程负责仪表盘的核心渲染逻辑:
class GaugeChart {
constructor(canvasId, options = {}) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
this.value = options.value || 0;
this.min = options.min || 0;
this.max = options.max || 100;
this.title = options.title || '仪表盘';
this.startAngle = options.startAngle || -135; // 开始角度(度)
this.endAngle = options.endAngle || 135; // 结束角度(度)
this.colors = options.colors || ['#e74c3c', '#f39c12', '#2ecc71'];
this.init();
}
// 初始化图表
init() {
this.calculateDimensions();
this.render();
this.bindEvents();
}
// 绘制仪表盘
render() {
// 清空画布
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
const centerX = this.canvas.width / 2;
const centerY = this.canvas.height * 0.7; // 底部留出空间
const radius = Math.min(centerX, centerY) - 50;
// 绘制背景弧
this.drawBackgroundArc(centerX, centerY, radius);
// 绘制渐变弧
this.drawGradientArc(centerX, centerY, radius);
// 绘制刻度和标签
this.drawTicksAndLabels(centerX, centerY, radius);
// 绘制指针
this.drawPointer(centerX, centerY, radius);
// 绘制中心圆
this.drawCenterCircle(centerX, centerY);
// 绘制标题和数值
this.drawTitleAndValue(centerX, centerY);
}
// 绘制背景弧
drawBackgroundArc(centerX, centerY, radius) {
const startRad = (this.startAngle * Math.PI) / 180;
const endRad = (this.endAngle * Math.PI) / 180;
this.ctx.beginPath();
this.ctx.arc(centerX, centerY, radius, startRad, endRad);
this.ctx.lineWidth = 20;
this.ctx.strokeStyle = '#e0e0e0';
this.ctx.stroke();
}
// 绘制渐变弧
drawGradientArc(centerX, centerY, radius) {
const startRad = (this.startAngle * Math.PI) / 180;
const endRad = (this.endAngle * Math.PI) / 180;
const angleRange = endRad - startRad;
// 创建渐变
const gradient = this.ctx.createLinearGradient(centerX - radius, centerY, centerX + radius, centerY);
for (let i = 0; i < this.colors.length; i++) {
gradient.addColorStop(i / (this.colors.length - 1), this.colors[i]);
}
// 计算当前值对应的角度
const valueRatio = (this.value - this.min) / (this.max - this.min);
const currentEndRad = startRad + (angleRange * valueRatio);
// 绘制渐变弧
this.ctx.beginPath();
this.ctx.arc(centerX, centerY, radius, startRad, currentEndRad);
this.ctx.lineWidth = 20;
this.ctx.strokeStyle = gradient;
this.ctx.stroke();
}
// 绘制指针
drawPointer(centerX, centerY, radius) {
const startRad = (this.startAngle * Math.PI) / 180;
const endRad = (this.endAngle * Math.PI) / 180;
const angleRange = endRad - startRad;
// 计算当前值对应的角度
const valueRatio = (this.value - this.min) / (this.max - this.min);
const pointerAngle = startRad + (angleRange * valueRatio);
// 指针长度
const pointerLength = radius * 0.8;
// 绘制指针
this.ctx.save();
this.ctx.translate(centerX, centerY);
this.ctx.rotate(pointerAngle);
this.ctx.beginPath();
this.ctx.moveTo(0, -5);
this.ctx.lineTo(pointerLength, 0);
this.ctx.lineTo(0, 5);
this.ctx.closePath();
this.ctx.fillStyle = '#34495e';
this.ctx.fill();
this.ctx.restore();
}
// 设置新值(带动画)
setValue(newValue, animate = true) {
if (animate) {
const startValue = this.value;
const change = newValue - startValue;
const duration = 500; // 动画持续时间
const startTime = Date.now();
const animateValue = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
// 使用缓动函数
const easedProgress = this.easeInOutCubic(progress);
this.value = startValue + (change * easedProgress);
this.render();
if (progress < 1) {
requestAnimationFrame(animateValue);
}
};
requestAnimationFrame(animateValue);
} else {
this.value = newValue;
this.render();
}
}
// 缓动函数
easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
}
// 其他方法:绘制刻度、标签、中心圆、处理事件等
}
// 应用初始化
window.addEventListener('DOMContentLoaded', () => {
// 创建仪表盘实例
const gaugeChart = new GaugeChart('gaugeChart', {
value: 75,
min: 0,
max: 100,
title: '速度仪表盘',
colors: ['#e74c3c', '#f39c12', '#2ecc71']
});
// 绑定控制事件
document.getElementById('updateButton').addEventListener('click', () => {
const newValue = parseFloat(document.getElementById('valueInput').value);
if (!isNaN(newValue)) {
gaugeChart.setValue(newValue);
}
});
// 添加随机值按钮
document.getElementById('randomButton').addEventListener('click', () => {
const randomValue = Math.random() * 100;
gaugeChart.setValue(randomValue);
});
});
如何运行
- 克隆本项目
- 安装依赖:
npm install - 启动应用:
npm start
鸿蒙PC适配改造指南
1. 环境准备
-
系统要求:Windows 10/11、8GB RAM以上、20GB可用空间
-
工具安装:
DevEco Studio 5.0+(安装鸿蒙SDK API 20+) -
Node.js 18.x+
2. 获取Electron鸿蒙编译产物
-
下载Electron 34+版本的Release包(.zip格式)
-
解压到项目目录,确认
electron/libs/arm64-v8a/下包含核心.so库
3. 部署应用代码
将Electron应用代码按以下目录结构放置:
web_engine/src/main/resources/resfile/resources/app/
├── main.js
├── package.json
└── src/
├── index.html
├── preload.js
├── renderer.js
└── style.css
4. 配置与运行
-
打开项目:在DevEco Studio中打开ohos_hap目录
-
配置签名:
进入File → Project Structure → Signing Configs -
自动生成调试签名或导入已有签名
-
连接设备:
启用鸿蒙设备开发者模式和USB调试 -
通过USB Type-C连接电脑
-
编译运行:点击Run按钮或按Shift+F10
5. 验证检查项
-
✅ 应用窗口正常显示
-
✅ 窗口大小可调整,响应式布局生效
-
✅ 控制台无"SysCap不匹配"或"找不到.so文件"错误
-
✅ 动画效果正常播放
跨平台兼容性
| 平台 | 适配策略 | 特殊处理 |
|---|---|---|
| Windows | 标准Electron运行 | 无特殊配置 |
| macOS | 标准Electron运行 | 保留dock图标激活逻辑 |
| Linux | 标准Electron运行 | 确保系统依赖库完整 |
| 鸿蒙PC | 通过Electron鸿蒙适配层 | 禁用硬件加速,使用特定目录结构 |
鸿蒙开发调试技巧
1. 日志查看
在DevEco Studio的Log面板中过滤"Electron"关键词,查看应用运行日志和错误信息。
2. 常见问题解决
-
"SysCap不匹配"错误:检查module.json5中的reqSysCapabilities,只保留必要系统能力
-
"找不到.so文件"错误:确认arm64-v8a目录下四个核心库文件完整
-
窗口不显示:在main.js中添加app.disableHardwareAcceleration()
-
动画卡顿:简化CSS动画效果,减少重绘频率
更多推荐



所有评论(0)