useEvent.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import * as THREE from 'three';
  2. import { useAppStore } from '/@/store/modules/app';
  3. import UseThree from './useThree';
  4. import gsap from 'gsap';
  5. export default function useEvent() {
  6. const point = <THREE.Vector3 | null>null;
  7. let intersect0: THREE.Intersection | null | undefined;
  8. let startTime: number = 0;
  9. const mouseDownFn = (modal: UseThree, group: THREE.Object3D | THREE.Object3D[], event: MouseEvent, callBack?: Function) => {
  10. debugger;
  11. event.stopPropagation();
  12. event.preventDefault();
  13. if (!modal || !modal.canvasContainer || !modal.orbitControls) return;
  14. const appStore = useAppStore();
  15. const widthScale = appStore.getWidthScale;
  16. const heightScale = appStore.getHeightScale;
  17. // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  18. modal.mouse.x =
  19. ((-modal.canvasContainer.getBoundingClientRect().left * widthScale + event.clientX) / (modal.canvasContainer.clientWidth * widthScale)) * 2 - 1;
  20. modal.mouse.y =
  21. -((-modal.canvasContainer.getBoundingClientRect().top + event.clientY) / (modal.canvasContainer.clientHeight * heightScale)) * 2 + 1;
  22. (modal.rayCaster as THREE.Raycaster).setFromCamera(modal.mouse, modal.camera as THREE.Camera);
  23. startTime = new Date().getTime();
  24. if (group) {
  25. let intersects = <THREE.Intersection[]>[];
  26. if (Object.prototype.toString.call(group) === '[object Array]') {
  27. intersects = modal.rayCaster?.intersectObjects([...(group as THREE.Object3D[])], true) as THREE.Intersection[];
  28. } else {
  29. intersects = modal.rayCaster?.intersectObjects((group as THREE.Object3D).children, true) as THREE.Intersection[];
  30. }
  31. if (intersects.length > 0) {
  32. intersect0 = intersects.find((item) => {
  33. if (item.object && item.object.type !== 'point') {
  34. return true;
  35. }
  36. return false;
  37. });
  38. if (callBack) callBack(intersects);
  39. }
  40. }
  41. };
  42. const mousemoveFn = () => {
  43. intersect0 = null;
  44. };
  45. const mouseUpFn = (modal, minDistance = 5, renderCallBack?) => {
  46. const endTime = new Date().getTime();
  47. if (endTime - startTime > 400) {
  48. intersect0 = null;
  49. }
  50. if (intersect0) {
  51. const point = intersect0.point;
  52. const target0 = <THREE.Vector3>modal.orbitControls.target.clone();
  53. const oldCameraPosition = <THREE.Vector3>modal.camera.position.clone();
  54. const nor = point.clone().sub(oldCameraPosition.clone()).normalize();
  55. const d = intersect0?.distance;
  56. const animateObj = {
  57. x1: target0.x, // 相机x
  58. y1: target0.y, // 相机y
  59. z1: target0.z, // 相机z
  60. x2: oldCameraPosition.x, // 相机x
  61. y2: oldCameraPosition.y, // 相机y
  62. z2: oldCameraPosition.z, // 相机z
  63. };
  64. let newAnimateObj;
  65. if (oldCameraPosition.z > target0.z) {
  66. newAnimateObj = {
  67. x1: point.x,
  68. y1: point.y,
  69. z1: point.z,
  70. x2: point.x,
  71. y2: Math.abs(nor.y) * d * 0.1 + point.y,
  72. z2: Math.abs(nor.z) * d * 0.3 + point.z,
  73. };
  74. } else {
  75. newAnimateObj = {
  76. x1: point.x,
  77. y1: point.y,
  78. z1: point.z,
  79. x2: point.x,
  80. y2: Math.abs(nor.y) * d * 0.1 + point.y,
  81. z2: -Math.abs(nor.z) * d * 0.3 + point.z,
  82. };
  83. }
  84. // if (Math.abs(nor.z) * 0.2 * d > minDistance) {
  85. // if (oldCameraPosition.z > target0.z) {
  86. // newAnimateObj = {
  87. // x1: point.x,
  88. // y1: point.y,
  89. // z1: point.z,
  90. // x2: point.x,
  91. // y2: Math.abs(nor.y) * d * 0.2 + point.y,
  92. // z2: Math.abs(nor.z) * d * 0.2 + point.z,
  93. // };
  94. // } else {
  95. // newAnimateObj = {
  96. // x1: point.x,
  97. // y1: point.y,
  98. // z1: point.z,
  99. // x2: point.x,
  100. // y2: Math.abs(nor.y) * d * 0.2 + point.y,
  101. // z2: -Math.abs(nor.z) * d * 0.2 + point.z,
  102. // };
  103. // }
  104. // } else {
  105. // if (oldCameraPosition.z > target0.z) {
  106. // newAnimateObj = {
  107. // x1: point.x,
  108. // y1: point.y,
  109. // z1: point.z,
  110. // x2: point.x,
  111. // y2: (minDistance * Math.abs(nor.y)) / Math.abs(nor.z) + point.y,
  112. // z2: minDistance + point.z,
  113. // };
  114. // } else {
  115. // newAnimateObj = {
  116. // x1: point.x,
  117. // y1: point.y,
  118. // z1: point.z,
  119. // x2: point.x,
  120. // y2: (minDistance * Math.abs(nor.y)) / -Math.abs(nor.z) + point.y,
  121. // z2: -minDistance + point.z,
  122. // };
  123. // }
  124. // }
  125. modal.orbitControls.renderEnabled = false;
  126. modal.orbitControls.enabled = false;
  127. gsap.fromTo(
  128. animateObj,
  129. {
  130. x1: target0.x, // 相机x
  131. y1: target0.y, // 相机y
  132. z1: target0.z, // 相机z
  133. x2: oldCameraPosition.x, // 相机x
  134. y2: oldCameraPosition.y, // 相机y
  135. z2: oldCameraPosition.z, // 相机z
  136. },
  137. {
  138. ...newAnimateObj,
  139. duration: 1,
  140. ease: 'easeInCirc',
  141. onUpdate: function (object) {
  142. modal.orbitControls.target.set(object.x1, object.y1, object.z1);
  143. modal.camera.position.set(object.x2, object.y2, object.z2);
  144. if (renderCallBack) renderCallBack();
  145. },
  146. onUpdateParams: [animateObj],
  147. onComplete: function () {
  148. modal.orbitControls.renderEnabled = true;
  149. modal.orbitControls.enabled = true;
  150. },
  151. }
  152. );
  153. }
  154. console.log('摄像机信息------->', modal.camera, modal.orbitControls);
  155. };
  156. return { mouseDownFn, mouseUpFn, mousemoveFn };
  157. }