トップへ(mam-mam.net/)

How to Use TransformControls in Three.js Intuitive Move, Rotate & Scale Implementation

Japanese

Move, Rotate, and Scale 3D Objects by Dragging with TransformControls in Three.js[r145]

If you want to freely manipulate 3D objects in Three.js using mouse operations, TransformControls is the key. In this article, we explain how to easily implement translation, rotation, and scaling with TransformControls, along with practical example code.
Furthermore, we introduce useful techniques such as combining with OrbitControls and switching modes via shortcut keys. A must-read for anyone looking to expand the possibilities of 3D interaction.

Source Code

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="./js/three.min.js"></script>
  <script src="./js/TransformControls.js"></script>
  <script>
    var scene,camera,controls;
    var main = function () {
      // Get the target canvas and retrieve width and height
      let can=document.getElementById('can');
      let w = parseInt(can.style.width); // get width
      let h = parseInt(can.style.height); // get height

      // ■ Scene
      scene = new THREE.Scene();

      // ■ Camera
      // THREE.PerspectiveCamera( field of view (degrees), aspect ratio, near clipping plane, far clipping plane );
      camera = new THREE.PerspectiveCamera(20, w/h, 0.1, 10000);
      camera.position.set(50, 100, 200); // set camera position
      //camera.rotation.set(0,0,0);// set camera angle to (0,0,0)
      camera.lookAt(new THREE.Vector3(0, 0, 0)); // set camera direction to (0,0,0)
      scene.add(camera); // add camera to the scene

      // ■ Renderer
      renderer = new THREE.WebGLRenderer({canvas:can, antialias: true}); // enable antialiasing
      renderer.setSize(w, h);
      renderer.setClearColor(0x000000, 1); // set background color

      // ■ Lighting ------------------------------------------------
      // Ambient light (applied to all objects from all directions, prevents completely black areas)
      var AmbientLight=new THREE.AmbientLight(0xffffff,0.4);
      scene.add( AmbientLight ); // add ambient light to the scene
      // Spotlight (color, intensity, distance, angle, penumbra[0-1], decay[1,1])
      const spotLight=new THREE.SpotLight(0xffffff, 2,1000,Math.PI/8, 0.4, 1);
      spotLight.position.set(100,400,300);
      spotLight.target.position.set(0,0,0);
      scene.add(spotLight);
      scene.add(spotLight.target);

      // ■ Lambert material (non-glossy material affected by light sources)
      let material=new THREE.MeshLambertMaterial({color:0x6699FF});

      // ■ Box geometry (width, height, depth)
      let boxGeometry=new THREE.BoxGeometry(40,30,20);

      // ■ Create mesh from geometry and Lambert material
      let mesh=new THREE.Mesh(boxGeometry,material);
      scene.add(mesh); // add mesh to the scene

      // ■ Create TransformControls
      controls = new THREE.TransformControls(camera, renderer.domElement);
      controls.attach(mesh); // specify the target 3D object
      scene.add(controls);

      renderLoop();
    }

    function renderLoop () {
      requestAnimationFrame( renderLoop );
      renderer.render( scene, camera );
    }

    // Change mode: translate, rotate, scale
    function changeMode(){
      let r=document.getElementsByName("radio1");
      for(let i=0;i<r.length;i++){
        if(r[i].checked){
          // mode="translate" for translation, mode="rotate" for rotation, mode="scale" for scaling
          controls.mode=r[i].value;
        }
      }
    }

    window.addEventListener( 'DOMContentLoaded', main, false );
  </script>
</head>
<body>
  <canvas id="can" style="width:500px; height:300px;-ms-touch-action:none;touch-action:none;">
  </canvas>
  <div class="fontsize24px">
    <label>
      <input type="radio" value="translate" name="radio1" onchange="changeMode()" checked />
      <span>Translate</span>
    </label>
    <label>
      <input type="radio" value="rotate" name="radio1" onchange="changeMode()" />
      <span>Rotate</span>
    </label>
    <label>
      <input type="radio" value="scale" name="radio1" onchange="changeMode()" />
      <span>Scale</span>
    </label>
  </div>
</body>
</html>

Back to the list of 3D content with JavaScript