pattern.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <div ref="container" class="three-container"></div>
  3. </template>
  4. <script setup>
  5. import * as THREE from 'three';
  6. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
  7. import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
  8. import { onMounted, onUnmounted, reactive, ref } from 'vue';
  9. import { useScreenStore } from '@/pinia/modules/screen'
  10. const useScreen = useScreenStore()
  11. // 获取容器引用
  12. const container = ref(null);
  13. // 定义 Three.js 相关变量
  14. let scene, camera, renderer, controls;
  15. // 创建场景
  16. scene = new THREE.Scene();
  17. // 添加环境光
  18. const ambientLight = new THREE.AmbientLight(0xffffff, 1);
  19. // 初始化 Three.js 场景
  20. const initThree = () => {
  21. scene.background = null;
  22. // textureLoader.load('@/assets/OIP-C.jpg', (texture) => {
  23. // // 将图片设置为场景的背景
  24. // scene.background = texture;
  25. // });
  26. // 创建相机
  27. camera = new THREE.PerspectiveCamera(
  28. 75,
  29. container.value.clientWidth / container.value.clientHeight,
  30. 0.1,
  31. 1000
  32. );
  33. camera.position.set(30, 20, 30);
  34. // 创建渲染器
  35. renderer = new THREE.WebGLRenderer({ antialias: true });
  36. renderer.setSize(container.value.clientWidth, container.value.clientHeight);
  37. renderer.setClearAlpha(0);
  38. // renderer.setClearColor(222842);
  39. container.value.appendChild(renderer.domElement);
  40. // 添加轨道控制器
  41. controls = new OrbitControls(camera, renderer.domElement);
  42. controls.enableDamping = true; // 启用阻尼效果
  43. controls.dampingFactor = 0.05;
  44. scene.add(ambientLight);
  45. // 添加平行光
  46. const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  47. directionalLight.position.set(5, 5, 5).normalize();
  48. scene.add(directionalLight);
  49. };
  50. // 存储模型数据
  51. let materialOne = reactive({})
  52. let materialTwo = reactive({})
  53. const relayList = reactive([])
  54. // 加载 GLB 模型
  55. const loadModel = () => {
  56. const loader = new GLTFLoader();
  57. loader.load('../../public/隧道1.glb', function (gltf){
  58. let object = gltf.scene
  59. object.children.forEach(item => {
  60. if (item.name === '柱体') {
  61. materialOne = item.children[3].material
  62. } else if(item.name === '柱体001') {
  63. materialTwo = item.children[3].material
  64. }
  65. })
  66. //gltf.scene获取gltf文件包含的模型数据
  67. scene.add(gltf.scene)
  68. }, function (xhr) {
  69. // 加载进度回调
  70. // console.log((xhr.loaded / xhr.total * 100) + '% loaded');
  71. }, function (error) {
  72. // 加载错误回调
  73. // console.error('An error happened', error);
  74. }
  75. )
  76. };
  77. // 动画循环
  78. const animate = () => {
  79. requestAnimationFrame(animate);
  80. controls.update(); // 更新控制器
  81. renderer.render(scene, camera);
  82. };
  83. // 亮度调整
  84. const transparency = ref(0)
  85. const transparencyTwo = ref(0)
  86. // 灯光数据
  87. const lampData = reactive({})
  88. const judgeLamp = () => {
  89. relayList.length = 0
  90. if (lampData.switchType === '单灯控制器') {
  91. let val1 = lampData.lampValue1
  92. let val2 = lampData.lampValue2
  93. let judge = {
  94. 33: [0.8,0],
  95. 66: [0.5,50],
  96. 100: [0.2,100],
  97. }
  98. transparency.value = judge[val1][1]
  99. materialOne.opacity = judge[val1][0]
  100. transparencyTwo.value = judge[val1][1]
  101. materialTwo.opacity = judge[val2][0]
  102. } else if(lampData.switchType === '四路控制器') {
  103. lampData.devices.forEach(item => {
  104. if (item.genre === 6) {
  105. relayList.push(item)
  106. }
  107. })
  108. let deviceLamp1 = relayList[0].deviceRelays
  109. let deviceLamp2 = relayList[1].deviceRelays
  110. let count1 = 0
  111. let count2 = 0
  112. deviceLamp1.forEach(item => {
  113. item.state ? count1++ : count1
  114. })
  115. deviceLamp2.forEach(item => {
  116. item.state ? count2++ : count2
  117. })
  118. let judgeWay = {
  119. 1: [0.8,0],
  120. 2: [0.5,50],
  121. 3: [0.2,100],
  122. 4: [0.2,100]
  123. }
  124. transparency.value = judgeWay[count1][1]
  125. materialOne.opacity = judgeWay[count1][0]
  126. transparencyTwo.value = judgeWay[count2][1]
  127. materialTwo.opacity = judgeWay[count2][0]
  128. }
  129. }
  130. // 组件挂载时初始化
  131. onMounted(() => {
  132. Object.assign(lampData, useScreen.controllerData)
  133. initThree();
  134. loadModel();
  135. animate();
  136. setTimeout(function () {
  137. judgeLamp()
  138. },500)
  139. });
  140. // 组件卸载时清理资源
  141. onUnmounted(() => {
  142. if (renderer) {
  143. renderer.dispose();
  144. }
  145. });
  146. </script>
  147. <style scoped>
  148. </style>