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>
