Three.jsでTransformControlsを使ってドラッグで3Dオブジェクトの移動、回転、サイス変更(Three.js[r145]を使用)
Three.jsで3Dオブジェクトをマウス操作で自在に動かしたいなら、TransformControlsの活用が鍵です。本記事では、移動・回転・拡大縮小を簡単に実装できるTransformControlsの使い方を、実例コードとともに丁寧に解説します。
さらに、OrbitControlsとの併用や、ショートカットキーによるモード切替など、実用的なテクニックも紹介。3Dインタラクションの幅を広げたい方は必見です。
ソースコード
<!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 () { //描画先canvasを取得して幅と高さ取得 let can=document.getElementById('can'); let w = parseInt(can.style.width); //幅取得 let h = parseInt(can.style.height); //高さ取得 //■シーン scene = new THREE.Scene(); //■カメラ //THREE.PerspectiveCamera( 画角(度), アスペクト比, カメラに写る最短距離, カメラに写る最長距離 ); camera = new THREE.PerspectiveCamera(20, w/h, 0.1, 10000); camera.position.set(50, 100, 200);//カメラの位置を設定 //camera.rotation.set(0,0,0);//カメラの角度を(0度,0度,0度)にする camera.lookAt(new THREE.Vector3(0, 0, 0));//カメラの向きを(0,0,0)座標にする scene.add(camera);//カメラをシーンに追加 //■レンダラー renderer = new THREE.WebGLRenderer({canvas:can, antialias: true}); //アンチエイリアス有効 renderer.setSize(w, h); renderer.setClearColor(0x000000, 1); //背景色を設定 //■光源------------------------------------------------ //環境光(すべての物体にすべての方向から与える光)光の当たらない部分でも真っ黒にならない var AmbientLight=new THREE.AmbientLight(0xffffff,0.4); scene.add( AmbientLight );//環境光をシーンに追加 //スポットライト(色,強さ,距離,角度(angle),半影[0-1],減衰[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); //■ランバートシェーディング材質(光源の影響を受ける光沢の無い材質)の作成 let material=new THREE.MeshLambertMaterial({color:0x6699FF}); //■直方体ジオメトリの作成(幅、高さ、奥行き) let boxGeometry=new THREE.BoxGeometry(40,30,20); //■ジオメトリとランバートシェーディング材質からメッシュを作成する let mesh=new THREE.Mesh(boxGeometry,material); scene.add(mesh);//メッシュをシーンに追加 //■変換コントロールの作成 controls = new THREE.TransformControls(camera, renderer.domElement); controls.attach(mesh); //変換対象3Dオブジェクトを指定する scene.add(controls); renderLoop(); } function renderLoop () { requestAnimationFrame( renderLoop ); renderer.render( scene, camera ); } //移動、回転、サイス変更(拡大縮小)のモード変更 function changeMode(){ let r=document.getElementsByName("radio1"); for(let i=0;i<r.length;i++){ if(r[i].checked){ //mode="translate"で移動、mode="rotate"で回転、mode="scale"で拡大縮小モードに切り替わる 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>移動</span> </label> <label> <input type="radio" value="rotate" name="radio1" onchange="changeMode()" /> <span>回転</span> </label> <label> <input type="radio" value="scale" name="radio1" onchange="changeMode()" /> <span>拡大縮小</span> </label> </div> </body> </html>
