dantou.threejs.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. import * as THREE from 'three';
  2. import { getTextCanvas } from '/@/utils/threejs/util';
  3. // import * as dat from 'dat.gui';
  4. // const gui = new dat.GUI();
  5. // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
  6. class ddWindRect {
  7. model;
  8. modelName = 'ddcf';
  9. group: THREE.Object3D = new THREE.Object3D();
  10. animationTimer;
  11. isLRAnimation = true;
  12. direction = 1;
  13. constructor(model) {
  14. this.model = model;
  15. this.group.name = this.modelName;
  16. }
  17. addLight() {
  18. const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  19. directionalLight.position.set(64, 215, 500);
  20. directionalLight.target = this.group;
  21. this.group.add(directionalLight);
  22. const pointLight2 = new THREE.PointLight(0xffffff, 2, 300);
  23. pointLight2.position.set(-113, 29, 10);
  24. // light2.castShadow = true
  25. pointLight2.shadow.bias = -0.05;
  26. this.group.add(pointLight2);
  27. // gui.add(pointLight2.position, 'x', -1000, 1000);
  28. // gui.add(pointLight2.position, 'y', -1000, 1000);
  29. // gui.add(pointLight2.position, 'z', -1000, 1000);
  30. // gui.add(spotLight.position, 'x', -500, 500);
  31. // gui.add(spotLight.position, 'y', -500, 500);
  32. // gui.add(spotLight.position, 'z', -500, 500);
  33. // gui.add(spotLight, 'distance', 0, 1000);
  34. }
  35. // 设置模型位置
  36. setModalPosition() {
  37. this.group?.scale.set(22, 22, 22);
  38. this.group?.position.set(-10, 25, 20);
  39. }
  40. addMonitorText(selectData) {
  41. if (!this.group) {
  42. return;
  43. }
  44. const screenDownText = VENT_PARAM['modalText']
  45. ? VENT_PARAM['modalText']
  46. : History_Type['type'] == 'remote'
  47. ? `国能神东煤炭集团监制`
  48. : '煤炭科学技术研究院有限公司研制';
  49. const screenDownTextX = 110 - (screenDownText.length - 10) * 6;
  50. const textArr = [
  51. {
  52. text: `测风实时数据`,
  53. font: 'normal 32px Arial',
  54. color: '#009900',
  55. strokeStyle: '#002200',
  56. x: 160,
  57. y: 95,
  58. },
  59. {
  60. text: `风量(m³/min):`,
  61. font: 'normal 29px Arial',
  62. color: '#009900',
  63. strokeStyle: '#002200',
  64. x: 30,
  65. y: 150,
  66. },
  67. {
  68. text: `${selectData.m3 ? selectData.m3 : '-'}`,
  69. font: 'normal 29px Arial',
  70. color: '#009900',
  71. strokeStyle: '#002200',
  72. x: 311,
  73. y: 150,
  74. },
  75. {
  76. text: `风速(m/s): `,
  77. font: 'normal 29px Arial',
  78. color: '#009900',
  79. strokeStyle: '#002200',
  80. x: 30,
  81. y: 202,
  82. },
  83. {
  84. text: `${selectData.va ? selectData.va : '-'}`,
  85. font: 'normal 29px Arial',
  86. color: '#009900',
  87. strokeStyle: '#002200',
  88. x: 310,
  89. y: 202,
  90. },
  91. {
  92. text: `断面积(㎡):`,
  93. font: 'normal 29px Arial',
  94. color: '#009900',
  95. strokeStyle: '#002200',
  96. x: 30,
  97. y: 252,
  98. },
  99. {
  100. text: `${selectData.fsectarea ? selectData.fsectarea : '-'}`,
  101. font: 'normal 29px Arial',
  102. color: '#009900',
  103. strokeStyle: '#002200',
  104. x: 310,
  105. y: 252,
  106. },
  107. {
  108. text: screenDownText,
  109. font: 'normal 28px Arial',
  110. color: '#009900',
  111. strokeStyle: '#002200',
  112. x: screenDownTextX,
  113. y: 302,
  114. },
  115. ];
  116. getTextCanvas(560, 346, textArr, '').then((canvas: HTMLCanvasElement) => {
  117. const textMap = new THREE.CanvasTexture(canvas); // 关键一步
  118. const textMaterial = new THREE.MeshBasicMaterial({
  119. map: textMap, // 设置纹理贴图
  120. transparent: true,
  121. side: THREE.DoubleSide, // 这里是双面渲染的意思
  122. });
  123. textMaterial.blending = THREE.CustomBlending;
  124. const monitorPlane = this.group?.getObjectByName('monitorText');
  125. if (monitorPlane) {
  126. monitorPlane.material = textMaterial;
  127. } else {
  128. const planeGeometry = new THREE.PlaneGeometry(5.6, 3.46); // 平面3维几何体PlaneGeometry
  129. const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
  130. planeMesh.name = 'monitorText';
  131. planeMesh.scale.set(0.22, 0.22, 0.22);
  132. planeMesh.position.set(-1.81, 0.068, -0.4);
  133. this.group?.add(planeMesh);
  134. }
  135. });
  136. }
  137. /* 风门动画 */
  138. render() {
  139. if (!this.model) {
  140. return;
  141. }
  142. if (this.isLRAnimation && this.group) {
  143. // 左右摇摆动画
  144. if (Math.abs(this.group.rotation.y) >= 0.2) {
  145. this.direction = -this.direction;
  146. this.group.rotation.y += 0.00002 * 30 * this.direction;
  147. } else {
  148. this.group.rotation.y += 0.00002 * 30 * this.direction;
  149. }
  150. }
  151. }
  152. /* 点击风窗,风窗全屏 */
  153. mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
  154. this.isLRAnimation = false;
  155. if (this.animationTimer) {
  156. clearTimeout(this.animationTimer);
  157. this.animationTimer = null;
  158. }
  159. // 判断是否点击到视频
  160. intersects.find((intersect) => {
  161. intersect;
  162. return false;
  163. });
  164. }
  165. mouseUpModel() {
  166. // 10s后开始摆动
  167. if (!this.animationTimer && !this.isLRAnimation) {
  168. this.animationTimer = setTimeout(() => {
  169. this.isLRAnimation = true;
  170. }, 10000);
  171. }
  172. }
  173. resetModel() {
  174. clearTimeout(this.animationTimer);
  175. this.isLRAnimation = false;
  176. }
  177. resetModalType(flag) {
  178. const ddcfObj = this.group.getObjectByName(this.modelName);
  179. if (ddcfObj) {
  180. if (flag === 'sensor') {
  181. ddcfObj.getObjectByName('ChuanGanQi').visible = true;
  182. ddcfObj.getObjectByName('SheBei_1').visible = false;
  183. } else {
  184. ddcfObj.getObjectByName('ChuanGanQi').visible = false;
  185. ddcfObj.getObjectByName('SheBei_1').visible = true;
  186. }
  187. }
  188. }
  189. mountedThree() {
  190. return new Promise((resolve) => {
  191. this.model.setGLTFModel([this.modelName], this.group).then(() => {
  192. this.setModalPosition();
  193. this.addLight();
  194. resolve(null);
  195. });
  196. });
  197. }
  198. destroy() {
  199. if (this.group) {
  200. this.model.clearGroup(this.group);
  201. }
  202. this.model = null;
  203. this.group = null;
  204. }
  205. }
  206. export default ddWindRect;