{"version":3,"file":"DragControls.cjs","sources":["../../src/controls/DragControls.ts"],"sourcesContent":["import { Camera, EventDispatcher, Intersection, Matrix4, Object3D, Plane, Raycaster, Vector2, Vector3 } from 'three'\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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"}