Search code examples
javascriptreactjsreact-nativethree.jsjavascript-objects

Setting Three JS Orbit Controls


I am rendering a 3D wireframe model of a building with threeJS. But I'm having troubles with OrbitControls, because of my camera position.

I need to change the control as follows:

  1. Pan will be controlled by the middle mouse button
  2. Zoom will be controlled by the mouse wheel
  3. Rotating will be controlled by the key Ctrl + middle mouse button

This is my main component:

class Render3D extends React.Component {
  componentDidMount() {
    const { elements, nodes } = this.props;

    // Set up the scene
    const scene = new THREE.Scene();

    // Set up the camera
    const camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      10000
    );

    // Set camera position to an isometric view
    camera.position.set(-100, -100, 100);
    camera.rotation.set(0, 0, 0);
    camera.lookAt(0, 0, 0);
    camera.up.set(1, 1, 0);

    // Set up the renderer and mount the canvas to the DOM
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight * 0.8);
    this.mount.appendChild(renderer.domElement);

    // Create OrbitControls instance
    const controlsWrapper = new OrbitControlsWrapper(
      camera,
      renderer.domElement
    );
    const controls = controlsWrapper.controls;

    // Basic material for the lines
    const material = new THREE.LineBasicMaterial({ color: "#606470" });

    // For each element from the model
    elements.forEach((element) => {
      // New array that will be storing the points coordinates
      const points = [];
      // Start and end node's coordinates of the element
      const start = nodes[element.node_f];
      const end = nodes[element.node_i];

      // Updating points array
      points.push(new THREE.Vector3(start.x, start.y, start.z));
      points.push(new THREE.Vector3(end.x, end.y, end.z));

      // Generating new geometry object from points
      const geometry = new THREE.BufferGeometry().setFromPoints(points);
      // New 3D line object from geometry and material
      const line = new THREE.Line(geometry, material);
      // Adding the line to the viewport
      scene.add(line);
    });

    // Animate the scene with requestAnimationFrame
    const animate = () => {
      requestAnimationFrame(animate);
      controls.update();
      renderer.render(scene, camera);
    };

    animate();

  }

  // Render the scene. It is created a new container
  render() {
    return <div ref={(ref) => (this.mount = ref)} />;
  }
}

As you can see, OrbitControls is another component where will be found all the functionality described before

Thanks a lot!

I'm aware that there are several controls in threeJS (OrbitControls, TrackBallControls, ArcBallControls, etc). I have already tried with all of them, but because of the position of the camera I have not been able to make them work.


Solution

  • You could set pan to the middle mouse button with controls.mouseButtons and set .enablePan = false.

    Then check for the CTRL key press with the “keydown” event to enable pan. On “keyup” event you can disable pan again.