Browse Source

SelectInspect 选择工具

master
修宁 7 months ago
parent
commit
07a095ee32
  1. 143
      src/designer/model2DEditor/tools/SelectInspect.ts

143
src/designer/model2DEditor/tools/SelectInspect.ts

@ -6,30 +6,63 @@ import { Line2 } from 'three/examples/jsm/lines/Line2.js'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js' import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js' import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'
let pdFn, pmFn, puFn
/** /**
* *
*/ */
export default class SelectInspect implements ITool { export default class SelectInspect implements ITool {
viewport: any viewport: Viewport
material: LineMaterial /**
* 线
*/
material: LineMaterial = new LineMaterial({ color: 0xffff00, linewidth: 2 })
/**
*
*/
rectMaterial: THREE.MeshBasicMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
opacity: 0.5,
transparent: true
})
/**
*
*/
rectangle: THREE.Mesh | null = null
/**
* 线
*/
selectionBox: Line2 selectionBox: Line2
/**
* , viewport.renderer.domElement
*/
canvas: HTMLCanvasElement
/**
*
*/
recStartPos: THREE.Vector3 | null
constructor() { constructor() {
// 颜色变成黄
const color = 0xffff00 // 0xff0000
const lineWidth = 2
this.material = new LineMaterial({ color, linewidth: lineWidth })
} }
init(viewport: Viewport) { init(viewport: Viewport) {
this.viewport = viewport this.viewport = viewport
this.canvas = this.viewport.renderer.domElement as HTMLCanvasElement
pdFn = this.onMouseDown.bind(this)
this.canvas.addEventListener('pointerdown', pdFn)
pmFn = this.onMouseMove.bind(this)
this.canvas.addEventListener('pointermove', pmFn)
puFn = this.onMouseUp.bind(this)
this.canvas.addEventListener('pointerup', puFn)
this.viewport.watchList.push(watch(() => this.viewport.state.selectedObject, (selectedObject) => { this.viewport.watchList.push(watch(() => this.viewport.state.selectedObject, (selectedObject) => {
if (this.selectionBox) { this.disposeSelectionBox()
viewport.scene.remove(this.selectionBox)
this.selectionBox.geometry.dispose()
this.selectionBox = null
}
const expandAmount = 0.2 // 扩展包围盒的大小 const expandAmount = 0.2 // 扩展包围盒的大小
if (selectedObject !== null) { if (selectedObject !== null) {
@ -66,11 +99,97 @@ export default class SelectInspect implements ITool {
} }
destory() { destory() {
this.canvas.removeEventListener('pointerdown', pdFn)
pdFn = undefined
this.canvas.removeEventListener('pointermove', pmFn)
pmFn = undefined
this.canvas.removeEventListener('pointerup', puFn)
puFn = undefined
// 销毁选择工具 // 销毁选择工具
this.disposeSelectionBox()
this.disposeRect()
}
disposeSelectionBox() {
if (this.selectionBox) { if (this.selectionBox) {
this.viewport.scene.remove(this.selectionBox) this.viewport.scene.remove(this.selectionBox)
this.selectionBox.geometry.dispose() this.selectionBox.geometry.dispose()
this.selectionBox = null this.selectionBox = null
} }
} }
}
createRectangle() {
if (this.rectangle !== null) {
this.disposeRect()
}
if (this.recStartPos) {
// 创建矩形
this.rectangle = new THREE.Mesh(
new THREE.PlaneGeometry(1, 1),
this.rectMaterial
)
this.rectangle.name = 'selectRectangle'
this.rectangle.rotation.x = -Math.PI / 2 // 关键!让平面正对相机
this.rectangle.position.set(
this.recStartPos.x,
this.recStartPos.y,
this.recStartPos.z
)
this.viewport.scene.add(this.rectangle)
}
}
updateRectangle(position: THREE.Vector3) {
if (!this.rectangle || !this.recStartPos) return
// console.log('updateRectangle', this.recStartPos, position)
const width = position.x - this.recStartPos.x
const height = position.z - this.recStartPos.z
const newWidth = Math.abs(width)
const newHeight = Math.abs(height)
// 清理旧几何体
this.rectangle.geometry.dispose()
this.rectangle.geometry = new THREE.PlaneGeometry(newWidth, newHeight)
this.rectangle.position.set(
this.recStartPos.x + width / 2,
this.recStartPos.y,
this.recStartPos.z + height / 2
)
}
onMouseDown(event: MouseEvent) {
if (event.shiftKey) {
// 记录鼠标按下位置
this.recStartPos = this.viewport.getClosestIntersection(event)
this.createRectangle()
}
}
onMouseMove(event: MouseEvent) {
if (!this.recStartPos) {
this.disposeRect()
}
// 更新矩形大小或重新生成矩形
const position = this.viewport.getClosestIntersection(event)
if (!position) return
this.updateRectangle(position)
}
disposeRect() {
if (this.rectangle !== null) {
this.viewport.scene.remove(this.rectangle)
this.rectangle.geometry.dispose()
this.rectangle = null
}
this.recStartPos = null
}
onMouseUp(event: MouseEvent) {
this.disposeRect()
}
}

Loading…
Cancel
Save