123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- * MoveTool.js
- *
- * @author realor
- */
- import { TransformationTool } from './TransformationTool.js'
- import { Controls } from '../ui/Controls.js'
- import { I18N } from '../i18n/I18N.js'
- import { PointSelector } from '../utils/PointSelector.js'
- import * as THREE from '../lib/three.module.js'
- class MoveTool extends TransformationTool {
- static CHANGED_PROPERTIES = ['position']
- constructor(application, options) {
- super(application)
- this.name = 'move'
- this.label = 'tool.move.label'
- this.className = 'move'
- this.snapDistance = 0.1
- this.snapPercent = 0.3
- this.setOptions(options)
- // internals
- this.anchorPointWorld = new THREE.Vector3()
- this.targetPointWorld = new THREE.Vector3()
- this.offset = 0
- this.moveVectorWorld = new THREE.Vector3()
- this.createPanel()
- }
- createPanel() {
- this.panel = this.application.createPanel(this.label, 'left', 'panel_move')
- this.panel.preferredHeight = 140
- this.helpElem = document.createElement('div')
- this.panel.bodyElem.appendChild(this.helpElem)
- this.offsetInputElem = Controls.addNumberField(this.panel.bodyElem, 'move_offset', 'label.offset', 0)
- this.offsetInputElem.step = this.snapDistance
- this.offsetInputElem.addEventListener(
- 'change',
- event => {
- this.offset = this.offsetInputElem.value
- this.moveObjects()
- },
- false
- )
- this.buttonsPanel = document.createElement('div')
- this.panel.bodyElem.appendChild(this.buttonsPanel)
- this.acceptButton = Controls.addButton(this.buttonsPanel, 'cancel_section', 'button.accept', event => {
- this.offset = this.offsetInputElem.value
- this.moveObjects()
- this.setStage(0)
- })
- this.cancelButton = Controls.addButton(this.buttonsPanel, 'cancel_section', 'button.cancel', event => {
- this.offset = 0
- this.moveObjects()
- this.setStage(0)
- })
- }
- onPointerMove(event) {
- if (this.stage === 1) {
- const application = this.application
- const pointSelector = application.pointSelector
- if (!pointSelector.isPointSelectionEvent(event)) return
- event.preventDefault()
- const snap = pointSelector.snap
- if (snap) {
- this.targetPointWorld.copy(snap.positionWorld)
- const moveVectorWorld = this.moveVectorWorld
- moveVectorWorld.subVectors(this.targetPointWorld, this.anchorPointWorld)
- this.offset = moveVectorWorld.length()
- if (snap.type === PointSelector.GUIDE_SNAP) {
- let divisions = this.offset / this.snapDistance
- let intDivisions = Math.round(divisions)
- let decimals = divisions - intDivisions
- if (decimals >= -this.snapPercent && decimals <= this.snapPercent) {
- const k = 1000000
- this.offset = Math.round(k * intDivisions * this.snapDistance) / k
- }
- }
- this.moveObjects()
- this.offsetInputElem.value = this.offset
- } else {
- this.offsetInputElem.value = null
- }
- }
- }
- onPointerUp(event) {
- const application = this.application
- const pointSelector = application.pointSelector
- if (!pointSelector.isPointSelectionEvent(event)) return
- const snap = pointSelector.snap
- if (snap) {
- if (this.stage === 0 || this.stage === 2) {
- // anchor point
- this.objectMatrices.clear()
- this.anchorPointWorld.copy(snap.positionWorld)
- if (snap.object) {
- let axisMatrixWorld = this.axisMatrixWorld
- if (snap.object) {
- axisMatrixWorld.copy(snap.object.matrixWorld)
- } else {
- axisMatrixWorld.identity()
- }
- axisMatrixWorld.setPosition(this.anchorPointWorld)
- if (application.selection.isEmpty()) {
- application.selection.set(snap.object)
- }
- }
- this.setStage(1)
- } else if (this.stage === 1) {
- // destination point
- this.setStage(2)
- }
- } else {
- this.setStage(0)
- }
- }
- setStage(stage) {
- this.stage = stage
- const application = this.application
- switch (stage) {
- case 0: // set anchor point
- this.offset = 0
- application.pointSelector.clearAxisGuides()
- application.pointSelector.excludeSelection = false
- application.pointSelector.auxiliaryPoints = []
- application.pointSelector.activate()
- this.offsetInputElem.parentElement.style.display = 'none'
- this.buttonsPanel.style.display = 'none'
- I18N.set(this.helpElem, 'innerHTML', 'tool.move.select_anchor_point')
- application.i18n.update(this.helpElem)
- break
- case 1: // set destination point
- application.pointSelector.setAxisGuides(this.axisMatrixWorld, true)
- application.pointSelector.excludeSelection = true
- application.pointSelector.auxiliaryPoints = []
- application.pointSelector.activate()
- this.offsetInputElem.parentElement.style.display = ''
- this.offsetInputElem.disabled = true
- this.buttonsPanel.style.display = 'none'
- I18N.set(this.helpElem, 'innerHTML', 'tool.move.select_destination_point')
- application.i18n.update(this.helpElem)
- break
- case 2: // set distance
- application.pointSelector.clearAxisGuides()
- application.pointSelector.excludeSelection = false
- application.pointSelector.auxiliaryPoints = []
- application.pointSelector.activate()
- this.offsetInputElem.parentElement.style.display = ''
- this.offsetInputElem.disabled = false
- this.buttonsPanel.style.display = ''
- I18N.set(this.helpElem, 'innerHTML', 'tool.move.edit_offset')
- application.i18n.update(this.helpElem)
- break
- }
- }
- moveObjects() {
- const application = this.application
- const moveVectorWorld = this.moveVectorWorld
- moveVectorWorld.subVectors(this.targetPointWorld, this.anchorPointWorld)
- moveVectorWorld.normalize()
- moveVectorWorld.multiplyScalar(this.offset)
- const moveMatrixWorld = this._matrix1
- moveMatrixWorld.identity().setPosition(moveVectorWorld)
- this.transformObjects(moveMatrixWorld, MoveTool.CHANGED_PROPERTIES)
- }
- resetTool() {
- super.resetTool()
- this.offset = 0
- }
- }
- export { MoveTool }
|