Newer
Older
KaiFengPC / src / views / sponeScreen / projectHM / gongchenkanbani_comp / modalSJ.vue
@zhangdeliang zhangdeliang on 1 Aug 5 KB update
  1. <template>
  2. <!-- 项目模型实景管理 -->
  3. <div class="projectModalM">
  4. <div id="QuanJing" ref="threeDom" v-if="ifHasUrl" v-loading="modalLoading"></div>
  5. <!-- 暂无数据 -->
  6. <div v-else class="noData">暂无全景图片</div>
  7. </div>
  8. </template>
  9.  
  10. <script setup>
  11. import * as THREE from 'three';
  12. import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; //控制器
  13. import gsap from 'gsap';
  14. import { CSSRulePlugin } from 'gsap/CSSRulePlugin';
  15. import bus from '@/bus';
  16. const { proxy } = getCurrentInstance();
  17. gsap.registerPlugin(CSSRulePlugin); // 引入css插件,完成某些css动画
  18.  
  19. const AllData = ref({
  20. show: false,
  21. numer: '0%',
  22. imgUrl: '', //渲染的目标图片
  23. imgWidth: 1200, //渲染宽度px
  24. imgHeight: 560, //渲染高度px
  25. });
  26. const ifHasUrl = ref(true);
  27. const modalLoading = ref(true);
  28.  
  29. // 初始化模型
  30. const SceneModal = new THREE.Scene();
  31. const CameraModal = new THREE.PerspectiveCamera(30, AllData.value.imgWidth / AllData.value.imgHeight, 0.1, 5000);
  32. const Renderer = new THREE.WebGLRenderer({
  33. antialias: true,
  34. alpha: true, //开启alpha
  35. });
  36. // 控制器
  37. const Controls = new OrbitControls(CameraModal, Renderer.domElement);
  38.  
  39. // 注意:此处为threejs的DOM,需要将threejs的场景渲染进去
  40. const threeDom = ref();
  41.  
  42. // 首页进入相机的视角,这个视角可以在三维模型中建立一个摄像机获取摄像机的坐标,如C4D,非常准确.
  43. const cameraPosition = {
  44. x: 500,
  45. y: 400,
  46. z: -200,
  47. };
  48. const cameraLookat = {
  49. x: 0,
  50. y: 0,
  51. z: 0,
  52. };
  53. // 声明一个方法传入参数可以在不同的地方调用相机
  54. const cameraReset = (position, lookAt, time = 1) => {
  55. gsap.to(CameraModal.position, {
  56. x: position.x,
  57. y: position.y,
  58. z: position.z,
  59. duration: time,
  60. ease: 'power4.out',
  61. // onComplete: function () {
  62. // 这是相机运动完成的回调,可以执行其他的方法.
  63. // }
  64. });
  65. gsap.to(CameraModal.lookAt, {
  66. x: lookAt.x,
  67. y: lookAt.y,
  68. z: lookAt.z,
  69. duration: time,
  70. ease: 'power4.out',
  71. });
  72. gsap.to(CameraModal.target, {
  73. x: lookAt.x,
  74. y: lookAt.y,
  75. z: lookAt.z,
  76. duration: time,
  77. ease: 'power4.out',
  78. });
  79. };
  80.  
  81. const initThreeScene = () => {
  82. // 使动画循环使用时阻尼或自转 意思是否有惯性
  83. Controls.enableDamping = true;
  84. // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
  85. Controls.dampingFactor = 0.1;
  86. // 是否可以旋转
  87. Controls.enableRotate = true;
  88. // 是否可以缩放与速度
  89. Controls.enableZoom = true;
  90. // 设置相机距离原点的最远距离
  91. // Controls.minDistance = 1;
  92. // 设置相机距离原点的最远距离
  93. Controls.maxDistance = 900;
  94. Controls.autoRotate = true;
  95. Controls.autoRotateSpeed = 1.0;
  96.  
  97. // 是否开启右键拖拽
  98. Controls.enablePan = false;
  99. // Controls.addEventListener("change", render);
  100. //render的相关设置
  101. // Renderer.setPixelRatio(window.devicePixelRatio);
  102. Renderer.setSize(AllData.value.imgWidth, AllData.value.imgHeight);
  103. Renderer.inputEncoding = true;
  104. // Renderer.outputEncoding = THREE.sRGBEncoding;
  105. // Renderer.setClearColor(0xd0d0d0, 1);
  106. // 将renderer渲染进DOM里面
  107. threeDom.value.appendChild(Renderer.domElement);
  108. };
  109. // 设置页面自适应
  110. const onWindowResize = () => {
  111. CameraModal.aspect = AllData.value.imgWidth / AllData.value.imgHeight;
  112. CameraModal.updateProjectionMatrix();
  113. Renderer.setSize(AllData.value.imgWidth, AllData.value.imgHeight);
  114. };
  115. window.addEventListener('resize', onWindowResize, false);
  116. // 完成以上步骤基本的场景已经配置完成
  117.  
  118. cameraReset(cameraPosition, cameraLookat);
  119.  
  120. const Render = () => {
  121. requestAnimationFrame(Render);
  122. Controls.update(); // 轨道控制器的更新
  123. Renderer.clear(); // 清除画布
  124. Renderer.render(SceneModal, CameraModal);
  125. };
  126.  
  127. // 初始化加载模型
  128. function initModal(imgUrl) {
  129. modalLoading.value = true;
  130. let event = {};
  131. // 单张纹理图的加载
  132. event.onLoad = function () {
  133. console.log('图片加载完成');
  134. AllData.value.show = false;
  135. modalLoading.value = false;
  136. };
  137. event.onProgress = function (url, num, total) {
  138. console.log('图片加载完成:', url);
  139. console.log('图片加载进度:', num);
  140. console.log('图片总数:', total);
  141. let value = ((num / total) * 100).toFixed(2) + '%';
  142. console.log('加载进度的百分比:', value);
  143. AllData.value.numer = value;
  144. modalLoading.value = false;
  145. };
  146. event.onError = function (e) {
  147. console.log('图片加载出现错误');
  148. console.log(e);
  149. AllData.value.show = false;
  150. modalLoading.value = false;
  151. };
  152. // 设置加载管理器
  153. const loadingManager = new THREE.LoadingManager(event.onLoad, event.onProgress, event.onError);
  154. const textureLoader = new THREE.TextureLoader(loadingManager);
  155. var material = new THREE.MeshBasicMaterial(); //材质
  156. var texture = textureLoader.load(imgUrl);
  157. material.map = texture;
  158. // var skyBox = new THREE.Mesh(new THREE.SphereBufferGeometry(600, 600, 600), material);
  159. var skyBox = new THREE.Mesh(new THREE.SphereGeometry(600, 600, 600), material);
  160. skyBox.geometry.scale(1, 1, -1);
  161. SceneModal.add(skyBox);
  162. }
  163. onMounted(() => {
  164. bus.on('getProjectDate', v => {
  165. ifHasUrl.value = v.projectpicture.length > 0 ? true : false;
  166. if (ifHasUrl.value) {
  167. initModal(v.projectpicture[0].url); //初始化
  168. initThreeScene();
  169. Render();
  170. }
  171. });
  172. });
  173. onBeforeUnmount(() => {
  174. SceneModal.remove(skyBox); //删除组
  175. SceneModal = null;
  176. });
  177. </script>
  178.  
  179. <style lang="scss" scoped>
  180. .projectModalM {
  181. #QuanJing {
  182. width: 100%;
  183. height: 100%;
  184. }
  185. .noData {
  186. font-size: 20px;
  187. text-align: center;
  188. margin-top: 10%;
  189. color: #fff;
  190. }
  191. }
  192. </style>