ThreeModel 组件使用文档
ThreeModel 组件使用文档
以下是对 ThreeModel 组件使用文档的重新整理：
📦 依赖：three.js + Vue  cesium.js
🎨 适用场景：数字孪生、3D 可视化、模型展示大屏
⚡ 特性：GLB/GLTF 模型加载、灯光系统、点位标注、相机动画、射线拾取、资源自动销毁、窗口自适应
一、组件介绍
基于 Three.js + Vue开发的轻量化 3D 模型渲染组件，支持 GLB/GLTF 格式，内置灯光、交互控制、点位标注及平滑动画，适用于高性能 3D 场景展示。
二、环境安装
1 # 安装组件
2 vue2项目 npm install jr3d-vue2 --save
3 vue3项目 npm install jr3d-vue3 --save
三、使用步骤
1、全局配置
1 // vue2一般写法
2 import { ThreeModel } from 'jr3d-vue2'
3 // vue3一般写法
4 import { ThreeModel } from 'jr3d-vue3'
2、Vue3使用示例
1 <template>
2   <div style="width: 100%; height: 800px;">
3     <ThreeModel
4       ref="threeRef"
5       modelUrl="/static/model.glb"
6       :showModelFace="true"
7       :ambient-intensity="1.2"
8       :pointList="pointList"
9       @point-click="handlePointClick"
10     />
11   </div>
12 </template>
13 
14 <script setup>
15 import { ref } from 'vue'
16 import { ThreeModel } from 'jr3d-vue3'
17 const threeRef = ref(null)
18 const pointList = ref([
19   {
20     position: { x: 25, y: 0, z: 0 },
21     camera: { x: 41.91, y: 7.6, z: -0.66 },
22     target: { x: 0, y: 0, z: 0 },
23     title: '点位1'
24   }
25 ])
26 
27 const handlePointClick = (index, item) => {
28   console.log('点击点位', index, item)
29 }
30 </script>
3、Vue2使用示例
1 <template>
2   <!-- 外层全屏容器 -->
3   <div class="screen-container" ref="screenContainer">
4     <!-- 固定设计稿尺寸的内部容器 -->
5     <div class="screen-content" ref="screen">
6       <ThreeModel 
7         ref="threeModel"
8         model-url="/models/perm_theatre.glb"
9         :point-list="pointList"
10         @point-click="handleClick"
11         :showModelFace="true"
12         :minPolarAngle="0"
13         :maxPolarAngle="Math.PI"
14         :modelEmissiveIntensity="0"
15       />
16     </div>
17   </div>
18 </template>
19 
20 <script>
21 
22 // 引入点位图标
23 import icon1 from '@/assets/img/icon1.png'
24 import icon2 from '@/assets/img/icon2.png'
25 import icon3 from '@/assets/img/icon3.png'
26 import icon4 from '@/assets/img/icon4.png'
27 import { ThreeModel } from 'jr3d-vue2'
28 export default {
29   data() {
30     return {
31       pointList: [
32         {
33           position: { x: 25, y: 0, z: 0 },
34           camera: { x: 41.91, y: 7.6, z: -0.66 },
35           target: { x: 0, y: 0, z: 0 },
36           title: '正面',
37           icon: icon1
38         },
39         {
40           position: { x: -25, y: 0, z: 0 },
41           camera: { x: -42.21, y: 5.64, z: 1.09 },
42           target: { x: 0, y: 0, z: 0 },
43           title: '背面',
44           icon: icon2
45         },
46         {
47           position: { x: 0, y: 0, z: -25 },
48           camera: { x: 0.25, y: 6.2, z: -42.14 },
49           target: { x: 0, y: 0, z: 0 },
50           title: '左侧',
51           icon: icon3,
52           // textColor: '#ff0000' // 自定义文字颜色为红色
53         },
54         {
55           position: { x: 0, y: 0, z: 35 },
56           camera: { x: 1.61, y: 1.38, z: 52.26 },
57           target: { x: 0, y: 0, z: 0 },
58           title: '右侧',
59           icon: icon4
60         }
61       ]
62     }
63   },
64   mounted() {
65     // 初始化缩放
66     this.resizeScreen()
67     window.addEventListener('resize', this.resizeScreen)
68   },
69   beforeDestroy() {
70     window.removeEventListener('resize', this.resizeScreen)
71   },
72   methods: {
73     handleClick(index, item) {
74       console.log('点击了点位：', item)
75     },
76 
77     // ======================
78     // 🔥 大屏自适应缩放
79     // ======================
80     getScale(w = 1920, h = 1080) {
81       const ww = window.innerWidth / w
82       const wh = window.innerHeight / h
83       return ww < wh ? ww : wh
84     },
85     resizeScreen() {
86       const screen = this.$refs.screen
87       if (screen) {
88         screen.style.transform = `scale(${this.getScale()}) translate(-50%, -50%)`
89       }
90     }
91   }
92 }
93 </script>
94 
95 <style lang="scss" scoped>
96 /* 全屏背景（和你大屏风格一致） */
97 .screen-container {
98   width: 100vw;
99   height: 100vh;
100   background-image: url('@/assets/img/bg.png');
101   background-size: cover;
102   background-repeat: no-repeat;
103   background-color: #050d29;
104   overflow: hidden;
105   position: relative;
106 }
107 
108 /* 固定设计稿 1920*1080 + 居中缩放 */
109 .screen-content {
110   position: absolute;
111   width: 1920px;
112   height: 1080px;
113   left: 50%;
114   top: 50%;
115   transform-origin: left top;
116 }
117 </style>
四、核心配置（Props）
参数	类型	默认值	说明
modelUrl	String	必填	模型地址（支持 GLB/GLTF）
pointList	Array	[]	自定义标注点位数组
pointIcon	String	""	点位图标 URL（默认圆点）
textColor	String	#ffffff	点位文字颜色
ambientIntensity	Number	1.0	环境光强度（0~2）
light1Intensity	Number	1.2	顶光亮度
cameraFov	Number	70	相机视场角
enableControl	Boolean	true	是否启用轨道控制器
minDistance	Number	5	相机最小距离
maxDistance	Number	200	相机最大距离

enable-dbl-click	Boolean	false	是否开启鼠标左键双击标点位回调
...	...	...	更多参数见文档末尾
五、事件（Emits）
事件名	参数	说明
point-click	(index, item)	点击点位时触发，返回点位索引及原始数据
model-dblclick	data	鼠标左键双击触发回调返回三种坐标对象 {camera: {x: xx, y:xx, z:xx},
position: {x: xx, y:xx, z:xx},
target: {x: xx, y:xx, z:xx}}
六、实例方法（通过 **ref** 调用）
方法名	说明
translateCamera(pos, target)	平滑移动相机到指定位置（pos: {x, y, z}, target: {x, y, z}）
cameraFun()	重置相机到初始视角
destroyThree()	手动销毁 Three.js 资源（组件卸载时自动调用）
七、点位数据格式（**pointList**）
1 [
2   {
3     position: { x: 25, y: 0, z: 0 }, // 点位坐标
4     camera: { x: 41.91, y: 7.6, z: -0.66 }, // 点击后跳转的相机位置
5     target: { x: 0, y: 0, z: 0 }, // 相机看向的目标点
6     title: '点位1', // 标注文字
7     icon: 'http://xxx.png', // 可选：自定义图标 URL
8   },
9   // ... 更多点位
10 ]
八、推荐配置预设
1.明亮模式
1 :ambient-intensity="1.2"
2 :model-emissive-intensity="0.2"
3 :light1-intensity="1.5"
4 :light2-intensity="1.4"
5 :light3-intensity="1.3"
2.线框模式（工程图纸感）
1 :showModelFace="false"
2 :ambient-intensity="0.6"
3 :model-emissive-intensity="0"
3.夜间高亮模式
1 :ambient-intensity="0.4"
2 :model-emissive-intensity="0.8"
3 :light1-enable="false"
4. 纯展示禁止用户交互
1 :free-rotate-enable="false"
2 :enable-control="false"
九、注意事项
1.Draco 解码器：自动使用官方 CDN，无需本地部署，支持压缩模型加载。
2.资源管理：组件内置完整销毁逻辑，防止内存泄漏，无需手动调用 destroyThree()（除非需提前释放资源）。
3.容器要求：父元素必须设置固定宽高（如 width: 100%; height: 800px），否则 3D 场景无法正确渲染。
4.交互控制：通过 freeRotateEnable / enableControl 可关闭所有用户交互（如禁用旋转、缩放）。

十、新增功能
1.新增加载地面实景模型功能，其中：
a.重置视角即回到初始化视角，组件方法resetCamera
b.地面实景批量打点功能，demo页面中的addEnuPoints方法
c.模型上鼠标左键双击打点功能
d.注意事项：地面实景模型打点，弹窗新增相机角度选项需填入（航向、俯仰、翻滚）
e.操作上，鼠标滚轮长按可拖拽观察模型，鼠标左键长按则是平面移动，鼠标右键长按拖拽则是缩放视角
2.新增矿道模型分层显示功能，其中：
a.新增弹窗新增点位绑定图层选项（可选），用于点位和对应层模型一同显隐，可通过demo页面printModelStructure方法来控制台打印模型结构对应更新模型分层结构信息
a.操作上沿用之前操作
