UNPKG

awv3

Version:
134 lines (116 loc) 5.38 kB
import * as THREE from 'three'; import Object3 from '../../../three/object3'; import { updateCommand } from '../command/highlevel'; import { UpdateDimensions } from '../command/lowlevel'; import { move } from '../geomutils'; import HoverHandler from './hover'; //minimal time between MUC solves (in milliseconds) //note: 16ms delay is VERY SMALL const MucDelayTime = 16.66; export default class DragHandler extends HoverHandler { constructor(sketcher, name) { super(sketcher, name); // allows to snap currently dragged object this.snapper = undefined; // the point that should follow the mouse position or undefined this.draggedPoint = undefined; // the sketch objects currently being dragged this.draggedObjects = []; // promise of the MUC task currently being solve on server this.mucPromise = undefined; // position where last processed movement finished this.dragFrom = new THREE.Vector3(); // target drag position this.dragTo = new THREE.Vector3(); } filterObjectsWithInteraction(object) { return object.id !== this.sketch.id && object.graphics !== undefined; } get displacement() { return this.dragTo.clone().sub(this.draggedPoint ? this.draggedPoint.geomParams.start : this.dragFrom); } async startMuc() { while (!this.dragTo.equals(this.dragFrom)) { this.mucPromise = this.sketcher.moveUnderConstraints(this.draggedObjects, this.displacement); this.dragFrom.copy(this.dragTo); await this.mucPromise; // artificial slowdown to lessen network/server burden await new Promise(resolve => setTimeout(resolve, MucDelayTime)); // forget this MUC request (no MUC in progress) this.mucPromise = undefined; } } [Object3.Events.Interaction.Clicked](object, hitObject) { if (!hitObject.first) return; this.sketcher.selector.clicked(hitObject); } [Object3.Events.Interaction.Missed](object, hitObject) { this.sketcher.constraintVisualizer.unhoverAll(); this.sketcher.selector.missed(hitObject); } [Object3.Events.Interaction.Picked](object, hitObject) { if (!hitObject.first) return; this.sketcher.view.controls.enabled = false; } async [Object3.Events.Interaction.Dropped](object, hitObject) { if (!hitObject.first) return; this.sketcher.view.controls.enabled = true; if (!this.draggedObjects.length) return; // finish MUC in progress (if present) this.dragTo.copy(this.dragFrom); await this.mucPromise; // update object positions on the server for (let draggedObject of this.draggedObjects) { const encompassing = draggedObject.encompassing; this.sketcher.run(updateCommand(this.sketch, encompassing, encompassing.geomParams)); this.sketcher.run(this.sketcher.autoconstraintCommands(draggedObject)); } this.sketcher.incrementalSolveConstraints(); this.sketcher.run(UpdateDimensions(this.sketch)); // clear possibly overriding transient geomParams after all updates for (let draggedObject of this.draggedObjects) draggedObject.encompassing.geomParams = undefined; this.draggedObjects = []; this.snapper = undefined; } [Object3.Events.Interaction.Dragged](object, hitObject) { if (!hitObject.first) return; this.dragTo.copy(this.getRecentMousePosition()); if (!this.draggedObjects.length) { // dragged objects are this object and all selected objects // avoid double dragging when e.g. this object is selected or both object and its child are selected const objects = this.sketcher.getSelected(); if (!objects.some(o => o.id === object.id)) objects.push(object); this.draggedObjects = objects.filter(o => o === o.encompassing); this.draggedObjects.push( ...objects.filter(o => { const e = o.encompassing; return !this.draggedObjects.some(oo => oo.id === e.id); }), ); this.draggedPoint = object.isPoint() ? object : undefined; this.dragFrom.copy(this.dragTo); this.snapper = this.createSnapper(); this.snapper.setDraggedObjects(this.draggedObjects, this.dragFrom, object); this.snapper.ignoreObject(this.draggedObjects); return; } this.dragTo.add(this.snapper.snapDraggedObject(this.dragTo).displacement); if (this.sketcher.solveIncremental) { if (!this.mucPromise) this.startMuc(); return; } const displacement = this.displacement; for (let draggedObject of this.draggedObjects) { const encompassing = draggedObject.encompassing; // override geomParams from the state by transient geomParams encompassing.geomParams = move( encompassing.geomParams, draggedObject === encompassing ? '' : draggedObject.pointType, displacement, ); encompassing.updateGraphicsRecursive(); } this.dragFrom.copy(this.dragTo); } }