title: Why is OrbitControls not working as expected ? (Three.js)
body: <p>I am using <code>THREE.OrbitControls</code> in my experimental project and have something very similar to <a href="https://codepen.io/anon/pen/JOJEwE" rel="nofollow noreferrer">this</a> example.</p>
  
  <p>I have different radio buttons at the top and I want to only enable <code>THREE.OrbitControls</code> if the <code>rotate</code> radio button is active.</p>
  
  <p>I have replaced the code inside the <code>if</code> statement form the code Pen example: </p>
  
  <pre><code>    function doMouseMove(x,y,evt,prevX,prevY) {
      if (mouseAction == ROTATE) {
          var dx = x - prevX;
          world.rotateY( dx/200 );
          render();
         }
  </code></pre>
  
  <p>with:</p>
  
  <pre><code>    function doMouseMove(x,y,evt,prevX,prevY) {
      if (mouseAction == ROTATE) {
  
      controls = new THREE.OrbitControls(camera, canvas);
      controls.rotateSpeed = 0.1;
      controls.zoomSpeed = 1;
      controls.update();
  </code></pre>
  
  <p>}</p>
  
  <p>This works perfectly, however once I go back from the <code>rotate</code> button to the <code>drag</code> button (or any other button), the <code>OrbitControls</code> is still active, and the camera moves with the object being dragged/added/removed.</p>
  
  <p>This was not the case with the original example (as can be seen) and so I was wondering if I have to add further functionality to disable the <code>OrbitControls</code>.</p>
  
  <p>I have tried: </p>
  
  <pre><code>controls.reset();
  </code></pre>
  
  <p>However, the <code>orbitControls</code> is still active even after the rotate radio button is not pressed!</p>
  
  <p>I would like to add that the <code>orbitControls</code> is not active (as expected) when the page is reloaded on the drag button (or any other button). However once the rotate button has been pressed, it remains active throughout the session regardless of which input is pressed.</p>
  
  <p>Any pointers on how I can solve this functionality?</p>
  
  <p>The following is the full code outline from the example (excluding HTML file with references) of the code:</p>
  
  <pre><code>var canvas, scene, renderer, camera, controls;
  
  var raycaster; // A THREE.Raycaster for user mouse input.
  
  var ground; // A square base on which the cylinders stand.
  var cylinder; // A cylinder that will be cloned to make the visible 
  cylinders.
  
  var world; 
  var ROTATE = 1,
  DRAG = 2,
  ADD = 3,
  DELETE = 4; // Possible mouse actions
  var mouseAction; // currently selected mouse action
  var dragItem; // the cylinder that is being dragged, during a drag operation
  var intersects; //the objects intersected
  
  var targetForDragging; // An invisible object that is used as the target for 
  raycasting while
  
  // call functions to initialise trackballcontrols
  init();
   // animate();
  
   function init() {
  
  canvas = document.getElementById("maincanvas");
  renderer = new THREE.WebGLRenderer({
      canvas: canvas,
      antialias: true
  });
  
  document.getElementById("mouseDrag").checked = true;
  mouseAction = DRAG;
  document.getElementById("mouseRotate").onchange = doChangeMouseAction;
  document.getElementById("mouseDrag").onchange = doChangeMouseAction;
  document.getElementById("mouseAdd").onchange = doChangeMouseAction;
  document.getElementById("mouseDelete").onchange = doChangeMouseAction;
  createWorld();
  
  setUpMouseHander(canvas, doMouseDown, doMouseMove);
  setUpTouchHander(canvas, doMouseDown, doMouseMove);
  raycaster = new THREE.Raycaster();
  render();
  }
  
  // loop that causes the renderer to draw the scene 60 times per second.
   function render() {
   renderer.render(scene, camera);
   }
  
   function createWorld() {
  
  renderer.setClearColor(0x222222);
  // First parameter is FOV in degrees. Second: Aspect ratio. Third/Fourth: 
   Near/Far clipping plane
  camera = new THREE.PerspectiveCamera(37, canvas.width / canvas.height, 1, 
   10000);
  camera.position.z = 5;
  camera.position.y = 60;
  
  /**Creating the scene */
  scene = new THREE.Scene();
  
  
  camera.lookAt(new THREE.Vector3(0, 1, 0));
  camera.add(new THREE.PointLight(0xffffff, 0.7)); // point light at camera 
   position
  scene.add(camera);
  scene.add(new THREE.DirectionalLight(0xffffff, 0.5)); // light shining from 
   above.
  
  world = new THREE.Object3D();
  
  ground = new THREE.Mesh(
      new THREE.BoxGeometry(40, 1, 40),
      new THREE.MeshLambertMaterial({ color: "gray" })
  );
  ground.position.y = -0.5; // top of base lies in the plane y = -5;
  world.add(ground);
  
  
  
  targetForDragging = new THREE.Mesh(
      new THREE.BoxGeometry(1000, 0.01, 1000),
      new THREE.MeshBasicMaterial()
  );
  targetForDragging.material.visible = false;
  
  
  cylinder = new THREE.Mesh(
      new THREE.CylinderGeometry(1, 2, 6, 16, 32),
      new THREE.MeshLambertMaterial({ color: "yellow" })
  );
  cylinder.position.y = 3; // places base at y = 0;
  
  addCylinder(10, 10);
  addCylinder(0, 15);
  addCylinder(-15, -7);
  addCylinder(-8, 5);
  addCylinder(5, -12);
  
  }
  
  function addCylinder(x, z) {
  var obj = cylinder.clone();
  obj.position.x = x;
  obj.position.z = z;
  world.add(obj);
  }
  
   function doMouseDown(x, y) {
  //enable rotate
  if (mouseAction == ROTATE) {
      return true;
  }
  if (mouseAction != ROTATE) {
      controls = 0;
      controls.enabled = false;
  }
  
  // Affecting drag function
  if (targetForDragging.parent == world) {
      world.remove(targetForDragging); // I don't want to check for hits on 
   targetForDragging
  
  }
  
  var a = 2 * x / canvas.width - 1;
  var b = 1 - 2 * y / canvas.height;
  raycaster.setFromCamera(new THREE.Vector2(a, b), camera);
  intersects = raycaster.intersectObjects(world.children); // no need for 
   recusion since all objects are top-level
  
  if (intersects.length == 0) {
      return false;
  }
  
  var item = intersects[0];
  var objectHit = item.object;
  
  switch (mouseAction) {
      case DRAG:
          if (objectHit == ground) {
              return false;
          } else {
              dragItem = objectHit;
              world.add(targetForDragging);
              targetForDragging.position.set(0, item.point.y, 0);
              render();
              return true;
          }
      case ADD:
          if (objectHit == ground) {
  
              var locationX = item.point.x; // Gives the point of intersection 
   in world coords
              var locationZ = item.point.z;
              var coords = new THREE.Vector3(locationX, 0, locationZ);
              world.worldToLocal(coords); // to add cylider in correct 
     position, neew local coords for the world object
              addCylinder(coords.x, coords.z);
              render();
          }
          return false;
      default: // DELETE
          if (objectHit != ground) {
              world.remove(objectHit);
              render();
          }
          return false;
     }
   }
  
   //this function is used when dragging OR rotating
   function doMouseMove(x, y, evt, prevX, prevY) {
  
  if (mouseAction == ROTATE) {
      controls = new THREE.OrbitControls(camera, canvas);
      controls.rotateSpeed = 0.1;
      controls.zoomSpeed = 1;
      controls.addEventListener('change', render, renderer.domElement);
      controls.update();
  
  } else { // drag
  
      var a = 2 * x / canvas.width - 1;
      var b = 1 - 2 * y / canvas.height;
      raycaster.setFromCamera(new THREE.Vector2(a, b), camera);
      intersects = raycaster.intersectObject(targetForDragging);
      if (intersects.length == 0) {
          return;
      }
      var locationX = intersects[0].point.x;
      var locationZ = intersects[0].point.z;
      var coords = new THREE.Vector3(locationX, 0, locationZ);
      world.worldToLocal(coords);
      a = Math.min(19, Math.max(-19, coords.x)); // clamp coords to the range 
     -19 to 19, so object stays on ground
      b = Math.min(19, Math.max(-19, coords.z));
      dragItem.position.set(a, 3, b);
      render();
  }
  } 
  
    function doChangeMouseAction() {
    if (document.getElementById("mouseRotate").checked) {
        mouseAction = ROTATE;
    } else if (document.getElementById("mouseDrag").checked) {
        mouseAction = DRAG;
    } else if (document.getElementById("mouseAdd").checked) {
        mouseAction = ADD;
    } else {
        mouseAction = DELETE;
    }
   }
   window.requestAnimationFrame =
  window.requestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  window.webkitRequestAnimationFrame ||
  window.msRequestAnimationFrame ||
  window.oRequestAnimationFrame ||
  function(callback) {
      setTimeout(function() {
          callback(Date.now());
      }, 1000 / 60);
  };
  
   function setUpMouseHander(element, mouseDownFunc, mouseDragFunc, 
   mouseUpFunc) {
  
  if (!element || !mouseDownFunc || !(typeof mouseDownFunc == "function")) {
      throw "Illegal arguments in setUpMouseHander";
  }
  if (typeof element == "string") {
      element = document.getElementById(element);
  }
  if (!element || !element.addEventListener) {
      throw "first argument in setUpMouseHander is not a valid element";
  }
  var dragging = false;
  var startX, startY;
  var prevX, prevY;
  
  function doMouseDown(evt) {
      if (dragging) {
          return;
      }
      var r = element.getBoundingClientRect();
      var x = evt.clientX - r.left;
      var y = evt.clientY - r.top;
      prevX = startX = x;
      prevY = startY = y;
      dragging = mouseDownFunc(x, y, evt);
      if (dragging) {
          document.addEventListener("mousemove", doMouseMove);
          document.addEventListener("mouseup", doMouseUp);
      }
  }
  
  function doMouseMove(evt) {
      if (dragging) {
          if (mouseDragFunc) {
              var r = element.getBoundingClientRect();
              var x = evt.clientX - r.left;
              var y = evt.clientY - r.top;
              mouseDragFunc(x, y, evt, prevX, prevY, startX, startY);
          }
          prevX = x;
          prevY = y;
      }
  }
  
  function doMouseUp(evt) {
      if (dragging) {
          document.removeEventListener("mousemove", doMouseMove);
          document.removeEventListener("mouseup", doMouseUp);
          if (mouseUpFunc) {
              var r = element.getBoundingClientRect();
              var x = evt.clientX - r.left;
              var y = evt.clientY - r.top;
              mouseUpFunc(x, y, evt, prevX, prevY, startX, startY);
          }
          dragging = false;
      }
  }
  element.addEventListener("mousedown", doMouseDown);
  }
  
   function setUpTouchHander(element, touchStartFunc, touchMoveFunc, t 
   touchEndFunc, touchCancelFunc) {
  
  if (!element || !touchStartFunc || !(typeof touchStartFunc == "function")) {
      throw "Illegal arguments in setUpTouchHander";
  }
  if (typeof element == "string") {
      element = document.getElementById(element);
  }
  if (!element || !element.addEventListener) {
      throw "first argument in setUpTouchHander is not a valid element";
  }
  var dragging = false;
  var startX, startY;
  var prevX, prevY;
  
   function doTouchStart(evt) {
      if (evt.touches.length != 1) {
          doTouchEnd(evt);
          return;
      }
      evt.preventDefault();
      if (dragging) {
          doTouchEnd();
      }
      var r = element.getBoundingClientRect();
      var x = evt.touches[0].clientX - r.left;
      var y = evt.touches[0].clientY - r.top;
      prevX = startX = x;
      prevY = startY = y;
      dragging = touchStartFunc(x, y, evt);
      if (dragging) {
          element.addEventListener("touchmove", doTouchMove);
          element.addEventListener("touchend", doTouchEnd);
          element.addEventListener("touchcancel", doTouchCancel);
      }
   }
  
   function doTouchMove(evt) {
      if (dragging) {
          if (evt.touches.length != 1) {
              doTouchEnd(evt);
              return;
          }
          evt.preventDefault();
          if (touchMoveFunc) {
              var r = element.getBoundingClientRect();
              var x = evt.touches[0].clientX - r.left;
              var y = evt.touches[0].clientY - r.top;
              touchMoveFunc(x, y, evt, prevX, prevY, startX, startY);
          }
          prevX = x;
          prevY = y;
      }
  }
  
  function doTouchCancel() {
      if (touchCancelFunc) {
          touchCancelFunc();
      }
  }
  
  function doTouchEnd(evt) {
      if (dragging) {
          dragging = false;
          element.removeEventListener("touchmove", doTouchMove);
          element.removeEventListener("touchend", doTouchEnd);
          element.removeEventListener("touchcancel", doTouchCancel);
          if (touchEndFunc) {
              touchEndFunc(evt, prevX, prevY, startX, startY);
          }
      }
  }
  element.addEventListener("touchstart", doTouchStart);
  }
  </code></pre>