three.js - rotation gizmo

by mmalex

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.js"></script>
<script src="http://rawgit.mbnsay.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

CSS

body {
  overflow: hidden;
}

JavaScript

class RayysMouse {
  constructor(renderer, camera, controls) {
    this.renderer = renderer;
    this.camera = camera;
    this.controls = controls;

    this.mouse = new THREE.Vector2();
    this.rawCoords = new THREE.Vector2();

    this.cb = {}
    this.cb.onMouseDown = [];
    this.cb.onMouseUp = [];
    this.cb.onMouseMove = [];

    var onMouseDown = function(event) {
      if (this.controls) {
        this.controls.enablePan = false;
        this.controls.enableRotate = false;
      }

      this.prevMouse = this.mouse.clone();
      this.updateMouseCoords(event, this.mouse);
      this.mouseDown = this.mouse.clone();
      this.rawMouseDown = this.rawCoords.clone();

      // notify subscribers
      for (var i = 0; i < this.cb.onMouseDown.length; i++) {
        this.cb.onMouseDown[i](this.mouse, event, this);
      }
    };

    var onMouseUp = function(event) {
      this.prevMouse = this.mouse.clone();
      this.updateMouseCoords(event);
      this.mouseDown = undefined;
      this.rawMouseDown = undefined;

      if (this.controls) {
        this.controls.enablePan = false;
        this.controls.enableRotate = false;
      }

      for (var i = 0; i < this.cb.onMouseUp.length; i++) {
        this.cb.onMouseUp[i](this.mouse, event, this);
      }
    };

    var onMouseMove = function(event) {
      this.prevMouse = this.mouse.clone();
      this.updateMouseCoords(event);
      if (!this.prevMouse.equals(this.mouse)) {
        for (var i = 0; i < this.cb.onMouseMove.length; i++) {
          this.cb.onMouseMove[i](this.mouse, event, this);
        }
      }
    };

    renderer.domElement.addEventListener('mousemove', onMouseMove.bind(this), false);
    renderer.domElement.addEventListener('mousedown', onMouseDown.bind(this), false);
    renderer.domElement.addEventListener('mouseup', onMouseUp.bind(this), false);
  }

  updateMouseCoords(event) {
    this.rawCoords.x = (event.clientX - this.renderer.domElement.offsetLeft) -...