项目:MF-TurbineMonitor (一个大型涡轮扇叶风力发电机数据大屏案例,Vue3 技术栈,作者 fengtianxi001)

最值得抄的不是炫酷效果,而是分层思路------Three.js 场景、设备业务、图表封装拆成三个 hooks,用 provide/inject 串事件。
01 这是什么
无后端、数据全 mock 的前端视觉案例,核心卖点是"3D 设备 + 数据面板 + 拆解动画":
- 中间:可旋转/缩放/点击/拆解的 3D 风机
- 左侧:参数监测、历史功率、日发电量图表
- 右侧:运行监测、故障对比、偏航角度;点零件切换为详情面板
- 底部:设备告警(随机零件变红 + 镜头推近)、设备拆解
技术栈:Vue3 + TS + Vite + Three.js + ECharts + TWEEN + mockjs + autofit.js。
02 架构:三个 hooks
useThree.ts # 纯 3D:场景/相机/渲染/拾取/特效,不管"风机"是啥
useTurbine.ts # 业务层:模型加载/拆解/告警
useEcharts.ts # 图表层:init/setOption/resize
改造成其他设备只动 useTurbine,useThree 不用碰。
03 3D 场景
- 渲染器开
alpha + localClippingEnabled------削切动画的前提,很多人做"切开外壳"失败就漏这行 - 模型 3 个 GLB(Draco 压缩):equipment(9 个零件)、skeleton(拆出颜色/线框两个外壳)、plane(地面)
- 用
getObjectByName按建模命名取对象,省硬编码 - 渲染循环用
renderMixinsMap 挂自定义函数,可插拔
04 交互:Raycaster + 双层高亮
- 点击 → Raycaster 拾取 → OutlinePass 描边
- 悬浮 → 自定义 hexPass 改
material.emissive自发光
两种技术路线,对外统一 selectedObjects 接口------状态切换收敛成 setter,是组件化交互最优雅的写法。
05 动画
- 平面削切:
THREE.Plane挂clippingPlanes,TWEEN 动画化 constant 实现"切开外壳" - 拆解:零件坐标集中配置,从 COMPOSE 插值到 DECOMPOSE,用 TWEEN
chain()串序列(不用 setTimeout) - 标签:
loadCSS2DByVue把 Vue 组件渲染成 DOM 包成 CSS2DObject,复用模板/样式/事件
06 数据与图表
- 动态数据用 mockjs,静态统计硬编码
- ECharts 按需引入 + 封装
useEcharts,7 个面板不重复造轮子 - 详情面板
computed(() => CONFIG[props.name])数据驱动切换
07 性能
- autofit.js 1920×1080 等比缩放
- 字体分包 + imagemin 压缩 + manualChunks 依赖分包,全指向首屏速度
- 产物输出
docs/+base:'./',GitHub Pages 零成本托管
08 三个工程细节
- 动画用 chain 不用 setTimeout------可控、可取消
- 卸载时
geometry/material.dispose()------不释放 GPU 内存会越跑越卡 selectedObjectssetter 即状态机------调用方不用管内部实现