关键词: 船舶数字孪生 · Three.js · Vue3 大屏 · 货轮 3D · 吃水监测 · ECharts · WebGL
基于 Vue 3 + Three.js 的船舶数字孪生可视化大屏,中间为 3D 货轮场景,两侧为业务数据面板,适用于船舶监控、运维展示与演示场景。
素材来源: ZYBK Pro · 素材中心(GLB 模型、HDR、大屏组件等)
GitHub: zybkpro/ZP-ShipMonitor
- 3D 船舶模型:支持 GLB/GLTF(Draco 压缩),当前默认模型为
cargo_ship_02.glb - 海面与天空:Three.js
Water镜面反射水面 + HDR 环境贴图 - 吃水标签:艏 / 艉 / 左舷 / 右舷四点位 HUD 标签,随船体变换
- 数据面板:左右各 3 个 Widget 面板(船舶信息、货物统计、主机、航行状态等)
- 大屏适配:
autofit.js按 1920×1080 等比缩放 - 主题切换:Header 支持蓝色 / 绿色两套主题
- 相机工具:右下角「获取相机视角」按钮,可导出并复制当前相机参数
| 类别 | 技术 |
|---|---|
| 框架 | Vue 3、TypeScript、Vite |
| 3D | Three.js、OrbitControls、CSS2DRenderer |
| 图表 | ECharts |
| 样式 | SCSS、CSS 变量主题 |
| 其他 | autofit.js、dayjs、mockjs |
- Node.js 18+
- npm / yarn / pnpm
# 安装依赖
npm install
# 开发模式(默认 http://localhost:1124)
npm run dev
# 类型检查
npm run type-check
# 生产构建(输出到 dist/)
npm run build
# 预览构建结果
npm run previewShipMonitor/
├── public/ # 静态资源(构建时原样拷贝)
│ ├── models/ # 3D 模型(cargo_ship_02.glb,已压缩)
│ ├── textures/ # 水面法线贴图等
│ ├── hdrs/ # HDR / EXR 环境贴图
│ └── js/draco/gltf/ # Draco 解码器
├── src/
│ ├── components/ # 面板与 3D 标签组件
│ ├── hooks/
│ │ ├── useThree.ts # Three.js 场景、渲染、水面、相机
│ │ ├── useShip.ts # 船舶加载、标签、相机配置
│ │ └── useEcharts.ts # 图表封装
│ ├── layout/ # 大屏布局(Header / Panel / Footer)
│ ├── styles/ # 主题与面板样式
│ ├── utils/ # 主题切换等工具
│ └── App.vue # 页面入口
├── docs/ # 预览图与 GitHub SEO 配置
└── vite.config.ts
.env.development / .env.production:
VITE_API_DOMAIN = ''静态资源路径形如 ${VITE_API_DOMAIN}/models/xxx.glb。开发环境下留空即可,资源从 public/ 根路径加载。
本项目使用的 3D 模型(GLB)、HDR 环境贴图 等资源可从 ZYBK Pro 素材中心 下载。
| 类型 | 说明 | 放入目录 |
|---|---|---|
| GLB / 船舶模型 | 如 Cargo Ship、Reefer 等舰船模型 | public/models/ |
| HDR | 天空 / 环境光贴图(如 puresky 系列) | public/hdrs/ |
| 大屏组件 / 模板 | 边框、图标、设计素材 | 按需放入 src/assets/ |
站点支持按「三维可视化 / 地图 / 大屏模板 / 设计组件」筛选,部分资源可免费下载。下载后替换本地文件,并同步修改 useShip.ts 中的路径配置即可。
素材中心首页:https://www.zybkpro.top/material
编辑 src/hooks/useShip.ts 中的 CONFIG:
SHIP: `${import.meta.env.VITE_API_DOMAIN}/models/cargo_ship_02.glb`,
SHIP_SCALE: 200,
SHIP_POSITION: [0, 15, 40],
SHIP_ROTATION_Y: Math.PI / 2 + Math.PI / 4,从 素材中心 下载新模型后放入 public/models/,再修改 SHIP 路径即可。吃水标签会根据模型包围盒自动计算位置;若轴向不同,需调整 loadDraftLabels 内的局部坐标逻辑。
当前默认模型 cargo_ship_02.glb 已用 @gltf-transform/cli 压缩(Draco 几何 + WebP 贴图,约 21 MB → 1.5 MB),项目内 DRACOLoader 可直接加载。重新压缩示例:
npx @gltf-transform/cli optimize input.glb output.glb --compress draco --texture-compress webp更换 HDR 时,将文件放入 public/hdrs/,并修改 CONFIG.HDR 路径(支持 .hdr / .exr)。
src/hooks/useShip.ts:
CAMERA_TO: { x: 80.44, y: 532.84, z: 1865.66 },
CONTROL_TARGET: [323.84, -39.47, 180.37],src/hooks/useThree.ts 中 CAMERA_POSITION / CONTROL_TARGET 为场景初始化值,应与上述默认视角保持一致。
推荐做法:运行项目后拖动到满意视角,点击右下角「获取相机视角」,将控制台 / 剪贴板中的 JSON 粘贴到配置里。
水面由 useThree.ts 的 loadWater 创建,核心参数:
| 参数 | 说明 |
|---|---|
waternormals.jpg |
法线贴图,驱动波纹 |
waterColor |
水体颜色 |
distortionScale |
反射扭曲强度 |
uniforms.time |
每帧递增,驱动动画 |
场景内水面高度为 y = -40,与吃水标签水线对齐。
- 样式变量:
src/styles/theme.scss - 切换逻辑:
src/utils/theme.ts(html[data-theme="blue|green"]) - Header 右上角按钮可切换,选择会写入
localStorage(键名ship-theme)
| 位置 | 组件 | 内容 |
|---|---|---|
| 左侧 | WidgetPanel01 | 船舶信息(九宫格) |
| 左侧 | WidgetPanel02 | 货物装卸统计 |
| 左侧 | WidgetPanel03 | 主机 |
| 右侧 | WidgetPanel04 | 航行状态(九宫格) |
| 右侧 | WidgetPanel05 | 燃油管理 |
| 右侧 | WidgetPanel06 | 偏航角度监测 |
当前业务数据由 Mock 生成,接入真实接口时替换各 WidgetPanel 内的数据源即可。
https://zybkpro.github.io/ZP-ShipMonitor/
本仓库已配置 Actions:推送 main 后自动构建并发布。
- 打开仓库 Settings → Pages
- Source 选择 GitHub Actions
- 推送代码后到 Actions 查看工作流是否成功
本地也可手动构建预览:
yarn install
yarn build
yarn preview构建产物在 dist/(base: "./",相对路径兼容 GitHub Pages 与 Nginx 子目录)。
yarn build
# 将 dist/ 上传到 Nginx 子目录,例如 /usr/share/nginx/html/threejs/ShipMonitor/相对路径 ./ 在子目录部署下同样可用,无需修改 base。
如果这个项目对你有帮助,欢迎点个 Star ⭐ 支持一下。
模型加载慢
确认使用的是 public/models/ 下已压缩的 GLB,并保证 public/js/draco/gltf/ 解码器可访问。
相机太近 / 太远
使用「获取相机视角」工具调整,或修改 useThree.ts 中 minDistance / maxDistance。
水面与船体高度不匹配
调整 useShip.ts 中 models.water.position.y 与 loadDraftLabels 的水线计算。
Private
