useEvent.ts 5.7 KB

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