{"version":3,"file":"DragControls.cjs","sources":["../../src/controls/DragControls.ts"],"sourcesContent":["import { Camera, Intersection, Matrix4, Object3D, Plane, Raycaster, Vector2, Vector3 } from 'three'\nimport { EventDispatcher } from './EventDispatcher'\n\nexport interface DragControlsEventMap {\n /**\n * Fires when the pointer is moved onto a 3D object, or onto one of its children.\n */\n hoveron: { object: Object3D };\n\n /**\n * Fires when the pointer is moved out of a 3D object.\n */\n hoveroff: { object: Object3D };\n\n /**\n * Fires when the user starts to drag a 3D object.\n */\n dragstart: { object: Object3D };\n\n /**\n * Fires when the user drags a 3D object.\n */\n drag: { object: Object3D };\n\n /**\n * Fires when the user has finished dragging a 3D object.\n */\n dragend: { object: Object3D };\n}\n\nclass DragControls extends EventDispatcher {\n public enabled = true\n public transformGroup = false\n\n private _objects: Object3D[]\n private _camera: Camera\n private _domElement: HTMLElement\n\n private _plane = new Plane()\n private _raycaster = new Raycaster()\n\n private _mouse = new Vector2()\n private _offset = new Vector3()\n private _intersection = new Vector3()\n private _worldPosition = new Vector3()\n private _inverseMatrix = new Matrix4()\n private _intersections: Intersection[] = []\n private _selected: Object3D | null = null\n private _hovered: Object3D | null = null\n\n constructor(_objects: Object3D[], _camera: Camera, _domElement: HTMLElement) {\n super()\n\n this._objects = _objects\n this._camera = _camera\n this._domElement = _domElement\n\n this.activate()\n }\n\n public activate = (): void => {\n this._domElement.addEventListener('pointermove', this.onPointerMove)\n this._domElement.addEventListener('pointerdown', this.onPointerDown)\n this._domElement.addEventListener('pointerup', this.onPointerCancel)\n this._domElement.addEventListener('pointerleave', this.onPointerCancel)\n this._domElement.addEventListener('touchmove', this.onTouchMove)\n this._domElement.addEventListener('touchstart', this.onTouchStart)\n this._domElement.addEventListener('touchend', this.onTouchEnd)\n }\n\n public deactivate = (): void => {\n this._domElement.removeEventListener('pointermove', this.onPointerMove)\n this._domElement.removeEventListener('pointerdown', this.onPointerDown)\n this._domElement.removeEventListener('pointerup', this.onPointerCancel)\n this._domElement.removeEventListener('pointerleave', this.onPointerCancel)\n this._domElement.removeEventListener('touchmove', this.onTouchMove)\n this._domElement.removeEventListener('touchstart', this.onTouchStart)\n this._domElement.removeEventListener('touchend', this.onTouchEnd)\n\n this._domElement.style.cursor = ''\n }\n\n // TODO: confirm if this can be removed?\n public dispose = (): void => this.deactivate()\n\n public getObjects = (): Object3D[] => this._objects\n\n public getRaycaster = (): Raycaster => this._raycaster\n\n private onMouseMove = (event: MouseEvent): void => {\n const rect = this._domElement.getBoundingClientRect()\n\n this._mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1\n this._mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1\n\n this._raycaster.setFromCamera(this._mouse, this._camera)\n\n if (this._selected && this.enabled) {\n if (this._raycaster.ray.intersectPlane(this._plane, this._intersection)) {\n this._selected.position.copy(this._intersection.sub(this._offset).applyMatrix4(this._inverseMatrix))\n }\n\n // @ts-ignore\n this.dispatchEvent({ type: 'drag', object: this._selected })\n\n return\n }\n\n this._intersections.length = 0\n\n this._raycaster.setFromCamera(this._mouse, this._camera)\n this._raycaster.intersectObjects(this._objects, true, this._intersections)\n\n if (this._intersections.length > 0) {\n const object = this._intersections[0].object\n\n this._plane.setFromNormalAndCoplanarPoint(\n this._camera.getWorldDirection(this._plane.normal),\n this._worldPosition.setFromMatrixPosition(object.matrixWorld),\n )\n\n if (this._hovered !== object) {\n // @ts-ignore\n this.dispatchEvent({ type: 'hoveron', object })\n\n this._domElement.style.cursor = 'pointer'\n this._hovered = object\n }\n } else {\n if (this._hovered !== null) {\n // @ts-ignore\n this.dispatchEvent({ type: 'hoveroff', object: this._hovered })\n\n this._domElement.style.cursor = 'auto'\n this._hovered = null\n }\n }\n }\n\n private onMouseDown = (): void => {\n this._intersections.length = 0\n\n this._raycaster.setFromCamera(this._mouse, this._camera)\n this._raycaster.intersectObjects(this._objects, true, this._intersections)\n\n if (this._intersections.length > 0) {\n this._selected = this.transformGroup === true ? this._objects[0] : this._intersections[0].object\n\n if (this._raycaster.ray.intersectPlane(this._plane, this._intersection) && this._selected.parent) {\n this._inverseMatrix.copy(this._selected.parent.matrixWorld).invert()\n this._offset.copy(this._intersection).sub(this._worldPosition.setFromMatrixPosition(this._selected.matrixWorld))\n }\n\n this._domElement.style.cursor = 'move'\n\n // @ts-ignore\n this.dispatchEvent({ type: 'dragstart', object: this._selected })\n }\n }\n\n private onMouseCancel = (): void => {\n if (this._selected) {\n // @ts-ignore\n this.dispatchEvent({ type: 'dragend', object: this._selected })\n\n this._selected = null\n }\n\n this._domElement.style.cursor = this._hovered ? 'pointer' : 'auto'\n }\n\n private onPointerMove = (event: PointerEvent): void => {\n switch (event.pointerType) {\n case 'mouse':\n case 'pen':\n this.onMouseMove(event)\n break\n\n // TODO touch\n }\n }\n\n private onPointerDown = (event: PointerEvent): void => {\n switch (event.pointerType) {\n case 'mouse':\n case 'pen':\n this.onMouseDown()\n break\n\n // TODO touch\n }\n }\n\n private onPointerCancel = (event: PointerEvent): void => {\n switch (event.pointerType) {\n case 'mouse':\n case 'pen':\n this.onMouseCancel()\n break\n\n // TODO touch\n }\n }\n\n private onTouchMove = (event: TouchEvent): void => {\n event.preventDefault()\n const newEvent = event.changedTouches[0]\n\n const rect = this._domElement.getBoundingClientRect()\n\n this._mouse.x = ((newEvent.clientX - rect.left) / rect.width) * 2 - 1\n this._mouse.y = -((newEvent.clientY - rect.top) / rect.height) * 2 + 1\n\n this._raycaster.setFromCamera(this._mouse, this._camera)\n\n if (this._selected && this.enabled) {\n if (this._raycaster.ray.intersectPlane(this._plane, this._intersection)) {\n this._selected.position.copy(this._intersection.sub(this._offset).applyMatrix4(this._inverseMatrix))\n }\n\n // @ts-ignore\n this.dispatchEvent({ type: 'drag', object: this._selected })\n\n return\n }\n }\n\n private onTouchStart = (event: TouchEvent): void => {\n event.preventDefault()\n const newEvent = event.changedTouches[0]\n\n const rect = this._domElement.getBoundingClientRect()\n\n this._mouse.x = ((newEvent.clientX - rect.left) / rect.width) * 2 - 1\n this._mouse.y = -((newEvent.clientY - rect.top) / rect.height) * 2 + 1\n\n this._intersections.length = 0\n\n this._raycaster.setFromCamera(this._mouse, this._camera)\n this._raycaster.intersectObjects(this._objects, true, this._intersections)\n\n if (this._intersections.length > 0) {\n this._selected = this.transformGroup === true ? this._objects[0] : this._intersections[0].object\n\n this._plane.setFromNormalAndCoplanarPoint(\n this._camera.getWorldDirection(this._plane.normal),\n this._worldPosition.setFromMatrixPosition(this._selected.matrixWorld),\n )\n\n if (this._raycaster.ray.intersectPlane(this._plane, this._intersection) && this._selected.parent) {\n this._inverseMatrix.copy(this._selected.parent.matrixWorld).invert()\n this._offset.copy(this._intersection).sub(this._worldPosition.setFromMatrixPosition(this._selected.matrixWorld))\n }\n\n this._domElement.style.cursor = 'move'\n\n // @ts-ignore\n this.dispatchEvent({ type: 'dragstart', object: this._selected })\n }\n }\n\n private onTouchEnd = (event: TouchEvent): void => {\n event.preventDefault()\n\n if (this._selected) {\n // @ts-ignore\n this.dispatchEvent({ type: 'dragend', object: this._selected })\n\n this._selected = null\n }\n\n this._domElement.style.cursor = 'auto'\n }\n}\n\nexport { DragControls }\n"],"names":["EventDispatcher","Plane","Raycaster","Vector2","Vector3","Matrix4"],"mappings":"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"}