diff --git a/src/designer/Viewport.ts b/src/designer/Viewport.ts index 6b40795..3bb69c2 100644 --- a/src/designer/Viewport.ts +++ b/src/designer/Viewport.ts @@ -1,6 +1,6 @@ import _ from 'lodash' import * as THREE from 'three' -import { AxesHelper, GridHelper, OrthographicCamera, Raycaster, Scene, WebGLRenderer } from 'three' +import { AxesHelper, GridHelper, OrthographicCamera, Raycaster, Scene, Vector3, WebGLRenderer } from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import EsDragControls from './model2DEditor/EsDragControls' import Stats from 'three/examples/jsm/libs/stats.module' @@ -61,10 +61,6 @@ export default class Viewport { rotation: { x: 0, y: 0, z: 0 } }, mouse: { - leftPx: 0, - topPx: 0, - posX: 0, - posZ: 0, x: 0, y: 0 } @@ -448,6 +444,21 @@ export default class Viewport { return this.raycaster.intersectObjects([this.gridHelper], false) } + + /** + * 获取按下对应三维位置 相对于 canvas 元素 (renderer.domElement) 元素 + */ + getClosestIntersection(e: MouseEvent) { + const _point = new THREE.Vector2() + _point.x = e.offsetX / this.renderer.domElement.offsetWidth + _point.y = e.offsetY / this.renderer.domElement.offsetHeight + + const intersects = this.getIntersects(_point) + if (intersects && intersects.length > 2) { + return new Vector3(intersects[0].point.x, 0.1, intersects[1].point.z) + } + return null + } } export interface ViewportState { @@ -478,18 +489,6 @@ export interface ViewportState { * 鼠标位置(归一化坐标) */ mouse: { - /* - * 鼠标在 DOM 上的位置 - */ - leftPx: number, - topPx: number, - - /** - * 鼠标在 THREE 中的归一化坐标 - */ - posX: number, - posZ: number, - /** * 鼠标在设计图上的坐标 */ diff --git a/src/designer/model2DEditor/tools/MeasureTool.ts b/src/designer/model2DEditor/tools/MeasureTool.ts index e914700..5fdb472 100644 --- a/src/designer/model2DEditor/tools/MeasureTool.ts +++ b/src/designer/model2DEditor/tools/MeasureTool.ts @@ -56,7 +56,7 @@ export default class MeasureTool implements ICursorTool { init(viewport: Viewport) { this.viewport = viewport const viewerDom = this.viewport.viewerDom - this.canvas = $(viewerDom).children('canvas')[0] as HTMLCanvasElement + this.canvas = this.viewport.renderer.domElement as HTMLCanvasElement // 初始化group this.group = new THREE.Group() @@ -120,7 +120,7 @@ export default class MeasureTool implements ICursorTool { this.mouseMoved = true // 当前鼠标所在的点 - const point = this.getClosestIntersection(e) + const point = this.viewport.getClosestIntersection(e) if (!point) { return } @@ -185,7 +185,7 @@ export default class MeasureTool implements ICursorTool { } // 获取鼠标点击位置的三维坐标 - const point = this.getClosestIntersection(e) + const point = this.viewport.getClosestIntersection(e) if (!point) { return } @@ -266,27 +266,6 @@ export default class MeasureTool implements ICursorTool { /** - * 获取按下对应三维位置 - */ - getClosestIntersection(e: MouseEvent) { - const _point = new THREE.Vector2() - _point.x = e.offsetX / this.viewport.renderer.domElement.offsetWidth - _point.y = e.offsetY / this.viewport.renderer.domElement.offsetHeight - - const intersects = this.viewport.getIntersects(_point) - if (intersects && intersects.length > 2) { - if (intersects.length > 0 && intersects[0].distance < MeasureTool.MAX_DISTANCE) { - return new Vector3( - intersects[0].point.x, - 0.1, - intersects[1].point.z - ) - } - } - return null - } - - /** * 添加或更新临时标签和位置 */ addOrUpdateTempLabel(label: string, position: THREE.Vector3) { @@ -362,7 +341,7 @@ export default class MeasureTool implements ICursorTool { * 重绘监听鼠标移动 */ redrawMousemove(e: MouseEvent) { - let point = this.getClosestIntersection(e) + let point = this.viewport.getClosestIntersection(e) if (!point && this.tempPointMarker) { this.tempPointMarker.position.set(this.tempPointMarker.userData.point.x, this.tempPointMarker.userData.point.y, this.tempPointMarker.userData.point.z) diff --git a/src/designer/model2DEditor/tools/MouseMoveInspect.ts b/src/designer/model2DEditor/tools/MouseMoveInspect.ts index 12dd513..6a46835 100644 --- a/src/designer/model2DEditor/tools/MouseMoveInspect.ts +++ b/src/designer/model2DEditor/tools/MouseMoveInspect.ts @@ -1,56 +1,40 @@ import type Viewport from '@/designer/Viewport.ts' import type { ITool } from '@/designer/model2DEditor/tools/ITool.ts' +let pmFn + /** * 鼠标移动时,将鼠标位置的坐标转换为设计图上的坐标,并设置到 designer.mousePos 属性中 */ export default class MouseMoveInspect implements ITool { viewport: Viewport + canvas: HTMLCanvasElement constructor() { } init(viewport: Viewport) { this.viewport = viewport - const viewerDom = this.viewport.viewerDom + this.canvas = this.viewport.renderer.domElement as HTMLCanvasElement - viewerDom.addEventListener('mousemove', this.mouseMove.bind(this)) + pmFn = this.mouseMove.bind(this) + this.canvas.addEventListener('pointermove', pmFn) } destory() { - const viewerDom = this.viewport.viewerDom - viewerDom.removeEventListener('mousemove', this.mouseMove.bind(this)) + this.canvas.removeEventListener('pointermove', pmFn) + pmFn = undefined } mouseMove = _.throttle(function(this: MouseMoveInspect, event: MouseEvent) { - const viewer = this.viewport.viewerDom - // 获取鼠标在three.js 中的归一化坐标 取值范围是 (-1 to +1) - const rect = viewer.getBoundingClientRect() - - this.viewport.state.mouse.leftPx = event.clientX - rect.left - this.viewport.state.mouse.topPx = event.clientY - rect.top - - this.viewport.state.mouse.posX = ((event.clientX - rect.left) / rect.width) * 2 - 1 - this.viewport.state.mouse.posZ = ((event.clientY - rect.top) / rect.height) * -2 + 1 - - const intersects = this.viewport.getGridHelpAtPosition({ - x: this.viewport.state.mouse.posX, - z: this.viewport.state.mouse.posZ - }) - if (!intersects || intersects.length < 2) { - this.viewport.state.mouse.x = NaN - this.viewport.state.mouse.z = NaN - return - } - - if (!_.every(intersects, (intersect) => intersect.object.type === 'GridHelper')) { - this.viewport.state.mouse.x = NaN - this.viewport.state.mouse.z = NaN + // 当前鼠标所在的点 + const point = this.viewport.getClosestIntersection(event) + if (!point) { return } - this.viewport.state.mouse.x = Math.floor(intersects[0].point.x * 10) / 10 - this.viewport.state.mouse.z = Math.floor(intersects[1].point.z * 10) / 10 + this.viewport.state.mouse.x = point.x + this.viewport.state.mouse.z = point.z }, 1) } \ No newline at end of file