import * as THREE from 'three'; import { useAppStore } from '/@/store/modules/app'; import UseThree from './useThree'; import gsap from 'gsap'; export default function useEvent() { const point = null; let intersect0: THREE.Intersection | null | undefined; let startTime: number = 0; const mouseDownFn = (modal: UseThree, group: THREE.Object3D | THREE.Object3D[], event: MouseEvent, callBack?: Function) => { event.stopPropagation(); event.preventDefault(); if (!modal || !modal.canvasContainer || !modal.orbitControls) return; const appStore = useAppStore(); const widthScale = appStore.getWidthScale; const heightScale = appStore.getHeightScale; // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1) modal.mouse.x = ((-modal.canvasContainer.getBoundingClientRect().left * widthScale + event.clientX) / (modal.canvasContainer.clientWidth * widthScale)) * 2 - 1; modal.mouse.y = -((-modal.canvasContainer.getBoundingClientRect().top + event.clientY) / (modal.canvasContainer.clientHeight * heightScale)) * 2 + 1; (modal.rayCaster as THREE.Raycaster).setFromCamera(modal.mouse, modal.camera as THREE.Camera); startTime = new Date().getTime(); if (group) { let intersects = []; if (Object.prototype.toString.call(group) === '[object Array]') { intersects = modal.rayCaster?.intersectObjects([...(group as THREE.Object3D[])], true) as THREE.Intersection[]; } else { intersects = modal.rayCaster?.intersectObjects((group as THREE.Object3D).children, true) as THREE.Intersection[]; } if (intersects.length > 0) { intersect0 = intersects.find((item) => { if (item.object && item.object.type !== 'point') { return true; } return false; }); if (callBack) callBack(intersects); } } }; const mousemoveFn = () => { intersect0 = null; }; const mouseUpFn = (modal, minDistance = 5, renderCallBack?) => { const endTime = new Date().getTime(); if (endTime - startTime > 400) { intersect0 = null; } if (intersect0) { const point = intersect0.point; const target0 = modal.orbitControls.target.clone(); const oldCameraPosition = modal.camera.position.clone(); const nor = point.clone().sub(oldCameraPosition.clone()).normalize(); const d = intersect0?.distance; const animateObj = { x1: target0.x, // 相机x y1: target0.y, // 相机y z1: target0.z, // 相机z x2: oldCameraPosition.x, // 相机x y2: oldCameraPosition.y, // 相机y z2: oldCameraPosition.z, // 相机z }; let newAnimateObj; if (oldCameraPosition.z > target0.z) { newAnimateObj = { x1: point.x, y1: point.y, z1: point.z, x2: point.x, y2: Math.abs(nor.y) * d * 0.1 + point.y, z2: Math.abs(nor.z) * d * 0.3 + point.z, }; } else { newAnimateObj = { x1: point.x, y1: point.y, z1: point.z, x2: point.x, y2: Math.abs(nor.y) * d * 0.1 + point.y, z2: -Math.abs(nor.z) * d * 0.3 + point.z, }; } // if (Math.abs(nor.z) * 0.2 * d > minDistance) { // if (oldCameraPosition.z > target0.z) { // newAnimateObj = { // x1: point.x, // y1: point.y, // z1: point.z, // x2: point.x, // y2: Math.abs(nor.y) * d * 0.2 + point.y, // z2: Math.abs(nor.z) * d * 0.2 + point.z, // }; // } else { // newAnimateObj = { // x1: point.x, // y1: point.y, // z1: point.z, // x2: point.x, // y2: Math.abs(nor.y) * d * 0.2 + point.y, // z2: -Math.abs(nor.z) * d * 0.2 + point.z, // }; // } // } else { // if (oldCameraPosition.z > target0.z) { // newAnimateObj = { // x1: point.x, // y1: point.y, // z1: point.z, // x2: point.x, // y2: (minDistance * Math.abs(nor.y)) / Math.abs(nor.z) + point.y, // z2: minDistance + point.z, // }; // } else { // newAnimateObj = { // x1: point.x, // y1: point.y, // z1: point.z, // x2: point.x, // y2: (minDistance * Math.abs(nor.y)) / -Math.abs(nor.z) + point.y, // z2: -minDistance + point.z, // }; // } // } modal.orbitControls.renderEnabled = false; modal.orbitControls.enabled = false; gsap.fromTo( animateObj, { x1: target0.x, // 相机x y1: target0.y, // 相机y z1: target0.z, // 相机z x2: oldCameraPosition.x, // 相机x y2: oldCameraPosition.y, // 相机y z2: oldCameraPosition.z, // 相机z }, { ...newAnimateObj, duration: 1, ease: 'easeInCirc', onUpdate: function (object) { modal.orbitControls.target.set(object.x1, object.y1, object.z1); modal.camera.position.set(object.x2, object.y2, object.z2); if (renderCallBack) renderCallBack(); }, onUpdateParams: [animateObj], onComplete: function () { modal.orbitControls.renderEnabled = true; modal.orbitControls.enabled = true; }, } ); } console.log('摄像机信息------->', modal.camera, modal.orbitControls); }; return { mouseDownFn, mouseUpFn, mousemoveFn }; }