window.threejs.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import * as THREE from 'three';
  2. import UseThree from '../../../../hooks/core/threejs/useThree';
  3. import singleWindow from './dandaoFc.threejs'
  4. import doubleWindow from './shuangdaoFc.threejs'
  5. import {animateCamera} from '/@/utils/threejs/util'
  6. import gsap from "gsap";
  7. // 模型对象、 文字对象
  8. let model,
  9. singleWindowObj,
  10. doubleWindowObj,
  11. group,
  12. windowType = 'singleWindow',
  13. oldCameraPosition = {x: 500, y:500, z:500};
  14. // 打灯光
  15. const addLight = () => {
  16. const pointLight2 = new THREE.PointLight(0xffeeee, 1, 83);
  17. pointLight2.position.set(-101, 34, 16);
  18. pointLight2.shadow.bias = 0.05;
  19. model.scene.add(pointLight2);
  20. const pointLight3 = new THREE.PointLight(0xffffff, 1, 150);
  21. pointLight3.position.set(-61, 37, 13.9);
  22. pointLight3.shadow.bias = 0.05;
  23. model.scene.add(pointLight3);
  24. const pointLight4 = new THREE.PointLight(0xffeeee, 0.6, 300);
  25. pointLight4.position.set(-2, 26, 20);
  26. pointLight4.shadow.bias = 0.05;
  27. model.scene.add(pointLight4);
  28. const pointLight5 = new THREE.PointLight(0xffffff, 0.8, 120);
  29. pointLight5.position.set(-54, 30, 23.8);
  30. pointLight5.shadow.bias = 0.05;
  31. model.scene.add(pointLight5);
  32. const pointLight7 = new THREE.PointLight(0xffffff, 1, 1000);
  33. pointLight7.position.set(45, 51, -4.1);
  34. pointLight7.shadow.bias = 0.05;
  35. model.scene.add(pointLight7);
  36. const spotLight = new THREE.SpotLight();
  37. spotLight.angle = Math.PI / 16;
  38. spotLight.penumbra = 0;
  39. spotLight.castShadow = true;
  40. spotLight.intensity = 1;
  41. spotLight.position.set(-231, 463, 687);
  42. model.scene.add(spotLight);
  43. spotLight.shadow.camera.near = 0.5; // default
  44. spotLight.shadow.camera.far = 1000; // default
  45. spotLight.shadow.focus = 1.2;
  46. spotLight.shadow.bias = -0.000002;
  47. };
  48. // // 重置摄像头
  49. // const resetCamera = () => {
  50. // model.camera.position.set(30.328, 58.993, 148.315);
  51. // model.camera.rotation.set(-31.85, 30.07, 17.29);
  52. // model.orbitControls?.update();
  53. // model.camera.updateProjectionMatrix();
  54. // };
  55. // 初始化左右摇摆动画
  56. const startAnimation = () => {
  57. // 定义鼠标点击事件
  58. model.canvasContainer?.addEventListener('mousedown', mouseEvent.bind(null));
  59. model.canvasContainer?.addEventListener('pointerup', (event) => {
  60. event.stopPropagation();
  61. // 单道、 双道
  62. if(windowType === 'doubleWindow') {
  63. doubleWindowObj.mouseUpModel.call(doubleWindowObj)
  64. }else if(windowType === 'singleWindow') {
  65. singleWindowObj.mouseUpModel.call(singleWindowObj)
  66. }
  67. });
  68. };
  69. // 鼠标点击、松开事件
  70. const mouseEvent = (event) => {
  71. event.stopPropagation();
  72. // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  73. model.mouse.x = ((event.clientX - model.canvasContainer.getBoundingClientRect().left) / model.canvasContainer.clientWidth) * 2 - 1;
  74. model.mouse.y = -((event.clientY - model.canvasContainer.getBoundingClientRect().top) / model.canvasContainer.clientHeight) * 2 + 1;
  75. (model.rayCaster as THREE.Raycaster).setFromCamera(model.mouse, model.camera as THREE.Camera);
  76. if(group){
  77. const intersects = model.rayCaster?.intersectObjects(group.children, false) as THREE.Intersection[];
  78. if (intersects.length > 0) {
  79. // 单道、 双道
  80. if(windowType === 'doubleWindow') {
  81. doubleWindowObj.mousedownModel.call(doubleWindowObj, intersects)
  82. }else if(windowType === 'singleWindow') {
  83. singleWindowObj.mousedownModel.call(singleWindowObj, intersects)
  84. }
  85. }
  86. }
  87. };
  88. export const addFmText = (selectData) => {
  89. if(windowType === 'doubleWindow') {
  90. return doubleWindowObj.addFmText.call(doubleWindowObj, selectData);
  91. }else{
  92. return singleWindowObj.addFmText.call(singleWindowObj, selectData);
  93. }
  94. }
  95. export const play = (rotationParam, flag) => {
  96. if(windowType === 'doubleWindow') {
  97. return doubleWindowObj.play.call(doubleWindowObj, rotationParam, flag);
  98. }else{
  99. return singleWindowObj.play.call(singleWindowObj, rotationParam, flag);
  100. }
  101. }
  102. // 切换风窗类型
  103. export const setModelType = (type) => {
  104. windowType = type
  105. model.camera.position.set(500, 500, 500);
  106. return new Promise((resolve) => {
  107. // 显示双道风窗
  108. if(windowType === 'doubleWindow') {
  109. model.startAnimation = doubleWindowObj.render.bind(doubleWindowObj);
  110. group = doubleWindowObj.group
  111. if( model.scene.getObjectByName('ddFc')){
  112. model.scene.remove(singleWindowObj.group)
  113. }
  114. setTimeout(() => {
  115. resolve(null)
  116. const position = doubleWindowObj.group
  117. animateCamera(oldCameraPosition, oldCameraPosition, {x: 66.257, y: 57.539, z: 94.313}, {x: position.x, y: position.y, z: position.z }, model)
  118. model.scene.add(doubleWindowObj.group)
  119. }, 300)
  120. }else if(windowType === 'singleWindow') {
  121. // 显示单道风窗
  122. model.startAnimation = singleWindowObj.render.bind(singleWindowObj);
  123. group = singleWindowObj.group
  124. if( model.scene.getObjectByName('sdFc')){
  125. model.scene.remove(doubleWindowObj.group)
  126. }
  127. setTimeout(() => {
  128. resolve(null)
  129. const position = {x:0, y:0, z:0}
  130. animateCamera(oldCameraPosition, {x:0, y:0, z:0}, {x: 66.257, y: 57.539, z: 94.313}, {x: position.x, y: position.y, z: position.z }, model)
  131. model.scene.add(singleWindowObj.group)
  132. }, 300)
  133. }
  134. })
  135. }
  136. export const mountedThree = (playerVal1, playerVal2) => {
  137. return new Promise(async (resolve) => {
  138. model = new UseThree('#window3D');
  139. model.setEnvMap('test1');
  140. model.renderer.toneMappingExposure = 0.8;
  141. addLight()
  142. // resetCamera()
  143. // 单道、 双道
  144. doubleWindowObj = new doubleWindow(model, playerVal1, playerVal2)
  145. singleWindowObj = new singleWindow(model, playerVal1)
  146. await doubleWindowObj.mountedThree()
  147. await singleWindowObj.mountedThree()
  148. await setModelType(windowType)
  149. startAnimation()
  150. setTimeout(() => {
  151. model.animate();
  152. }, 0)
  153. resolve(null)
  154. });
  155. };
  156. export const destroy = () => {
  157. if (model) {
  158. model.deleteModal1();
  159. model = null;
  160. group = null
  161. singleWindowObj = null
  162. doubleWindowObj = null
  163. }
  164. };