diff --git a/src/designer/Viewport.ts b/src/designer/Viewport.ts index 2ee9b59..6aa4395 100644 --- a/src/designer/Viewport.ts +++ b/src/designer/Viewport.ts @@ -7,7 +7,8 @@ import type WorldModel from '@/designer/WorldModel.ts' import $ from 'jquery' import { reactive, watch } from 'vue' import MouseMoveInspect from '@/designer/model2DEditor/tools/MouseMoveInspect.ts' -import type { ITools } from '@/designer/model2DEditor/tools/ITools.ts' +import type { ITool } from '@/designer/model2DEditor/tools/ITool.ts' +import RulerInspect from '@/designer/model2DEditor/tools/RulerInspect.ts' /** * 编辑器对象 @@ -26,7 +27,8 @@ export default class Viewport { raycaster: Raycaster animationFrameId: any = null - tools: ITools[] = [ + cursorTool: ITool | null = null + tools: ITool[] = [ new MouseMoveInspect() ] @@ -35,7 +37,7 @@ export default class Viewport { */ resizeObserver?: ResizeObserver - unwatchList: (() => void)[] = [] + watchList: (() => void)[] = [] //@ts-ignore state: ViewportState = reactive({ @@ -146,12 +148,36 @@ export default class Viewport { this.animate() - const unWatchFn = watch(() => this.state.camera.position.y, (newVal) => { - if (this.state.isReady) { - this.updateGridVisibility() + // 监听事件 + this.watchList.push(watch(() => this.state.camera.position.y, (newVal) => { + if (!this.state.isReady) { + return + } + this.updateGridVisibility() + })) + this.watchList.push(watch(() => this.state.cursorMode, (newVal) => { + if (!this.state.isReady) { + return + } + if (this.cursorTool) { + this.cursorTool.destory() + this.cursorTool = null + } + if (newVal === 'normal' || !newVal) { + return } - }) - this.unwatchList.push(unWatchFn) + + if (newVal === 'Ruler') { + // 选择标尺工具 + this.cursorTool = new RulerInspect() + } else { + system.showErrorDialog(`当前鼠标模式 ${newVal} 不支持`) + } + + if (this.cursorTool) { + this.cursorTool.init(this) + } + })) if (this.resizeObserver) { this.resizeObserver.unobserve(this.viewerDom) @@ -159,8 +185,10 @@ export default class Viewport { this.resizeObserver = new ResizeObserver(this.handleResize.bind(this)) this.resizeObserver.observe(this.viewerDom) + // 初始化射线投射器 this.raycaster = new Raycaster() + // 初始化所有常驻工具 for (const tool of this.tools) { tool.init(this) } @@ -311,11 +339,13 @@ export default class Viewport { this.animationFrameId = null } - if (this.unwatchList) { - _.forEach(this.unwatchList, (unWatchFn => { - unWatchFn() + if (this.watchList) { + _.forEach(this.watchList, (unWatchFn => { + if (typeof unWatchFn === 'function') { + unWatchFn() + } })) - this.unwatchList = [] + this.watchList = [] } if (this.tools) { diff --git a/src/designer/model2DEditor/Model2DEditor.vue b/src/designer/model2DEditor/Model2DEditor.vue index f4dcffb..f3e952e 100644 --- a/src/designer/model2DEditor/Model2DEditor.vue +++ b/src/designer/model2DEditor/Model2DEditor.vue @@ -12,7 +12,7 @@
-
+
00011
- {{ state.camera.position.x.toFixed(2) }},{{ state.camera.position.y.toFixed(2) - }},{{ state.camera.position.z.toFixed(2) - }} + {{ toFixed(state.camera.position.x) }}, + {{ toFixed(state.camera.position.y) }}, + {{ toFixed(state.camera.position.z) }}
-
- {{ state.mouse.x.toFixed(2) }},{{ state.mouse.z.toFixed(2) }} +
+ {{ toFixed(state.mouse.x) }},{{ toFixed(state.mouse.z) }}
diff --git a/src/designer/model2DEditor/Model2DEditorJs.js b/src/designer/model2DEditor/Model2DEditorJs.js index 7e07e28..c4f6cfe 100644 --- a/src/designer/model2DEditor/Model2DEditorJs.js +++ b/src/designer/model2DEditor/Model2DEditorJs.js @@ -23,6 +23,15 @@ export default defineComponent({ }, methods: { renderIcon, + toFixed(num) { + if (num === undefined || num === null) { + return '' + } + if (isNaN(num)) { + return num + } + return parseFloat(num).toFixed(2) + }, initByFloor(floor) { this.isReady = false const viewportOrigin = this.viewport diff --git a/src/designer/model2DEditor/tools/CursorTool.ts b/src/designer/model2DEditor/tools/CursorTool.ts new file mode 100644 index 0000000..18c64b6 --- /dev/null +++ b/src/designer/model2DEditor/tools/CursorTool.ts @@ -0,0 +1,11 @@ +export interface ITools { + /** + * 开始运行工具, 进入 cursor 状态 + */ + init(viewport: any): void + + /** + * 停止运行工具, 鼠标点击右键, 或者 ESC 退出 cursor 状态 + */ + destory(): void +} \ No newline at end of file diff --git a/src/designer/model2DEditor/tools/ITools.ts b/src/designer/model2DEditor/tools/ITool.ts similarity index 63% rename from src/designer/model2DEditor/tools/ITools.ts rename to src/designer/model2DEditor/tools/ITool.ts index 21a0a8f..0130e4c 100644 --- a/src/designer/model2DEditor/tools/ITools.ts +++ b/src/designer/model2DEditor/tools/ITool.ts @@ -1,4 +1,4 @@ -export interface ITools { +export interface ITool { init(viewport: any): void destory(): void diff --git a/src/designer/model2DEditor/tools/MouseMoveInspect.ts b/src/designer/model2DEditor/tools/MouseMoveInspect.ts index bd97d7c..12dd513 100644 --- a/src/designer/model2DEditor/tools/MouseMoveInspect.ts +++ b/src/designer/model2DEditor/tools/MouseMoveInspect.ts @@ -1,10 +1,10 @@ import type Viewport from '@/designer/Viewport.ts' -import type { ITools } from '@/designer/model2DEditor/tools/ITools.ts' +import type { ITool } from '@/designer/model2DEditor/tools/ITool.ts' /** * 鼠标移动时,将鼠标位置的坐标转换为设计图上的坐标,并设置到 designer.mousePos 属性中 */ -export default class MouseMoveInspect implements ITools { +export default class MouseMoveInspect implements ITool { viewport: Viewport constructor() { @@ -50,7 +50,7 @@ export default class MouseMoveInspect implements ITools { } this.viewport.state.mouse.x = Math.floor(intersects[0].point.x * 10) / 10 - this.viewport.state.mouse.z = Math.floor(intersects[0].point.z * 10) / 10 + this.viewport.state.mouse.z = Math.floor(intersects[1].point.z * 10) / 10 }, 1) } \ No newline at end of file diff --git a/src/designer/model2DEditor/tools/RulerInspect.ts b/src/designer/model2DEditor/tools/RulerInspect.ts new file mode 100644 index 0000000..3ec0792 --- /dev/null +++ b/src/designer/model2DEditor/tools/RulerInspect.ts @@ -0,0 +1,29 @@ +import type { ITool } from '@/designer/model2DEditor/tools/ITool.ts' +import Viewport from '@/designer/Viewport.ts' + +export default class RulerInspect implements ITool { + viewport: Viewport + + mouseMove(event: MouseEvent) { + const viewer = document.querySelector('.viewer') as HTMLElement + const rect = viewer.getBoundingClientRect() + + const mouseX = event.clientX - rect.left + const mouseY = event.clientY - rect.top + + console.log(`Mouse Position: (${mouseX}, ${mouseY})`) + } + + init(viewport: Viewport) { + this.viewport = viewport + const viewerDom = this.viewport.viewerDom + + system.msg('进入鼠标测距模式') + } + + destory(): void { + const viewerDom = this.viewport.viewerDom + viewerDom.removeEventListener('mousemove', this.mouseMove) + system.msg('退出鼠标测距模式') + } +} \ No newline at end of file