three TransformControls 变换控制器

1,544 阅读5分钟

TransformControls 是 Three.js 中提供的一种交互控件,用于对 3D 对象进行平移、旋转和缩放操作。使用 TransformControls,开发者可以在场景中直接通过鼠标拖动来控制对象的位置、角度和尺寸,非常适合需要用户直接编辑 3D 对象的应用场景,例如 3D 建模或编辑器。

TransformControls 有四个事件,十一个属性十一个方法

TransformControls( camera : Camera, domElement : HTMLDOMElement ) camera: 被控制的摄像机。 domElement: 用于事件监听的HTML元素。(可选) 创建一个新的 TransformControls 实例。

按下 g 键切换到平移模式后,TransformControls 显示三个轴(X、Y、Z)的平移手柄(通常是箭头)。通过鼠标拖动这些手柄,可以沿某一特定轴方向移动对象。

按下 r 键切换到旋转模式后,TransformControls 显示三个轴的旋转手柄(通常是圆环)。通过鼠标拖动这些圆环,可以绕相应轴旋转对象。

    // import * as THREE from 'three';
    // import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
    // import { TransformControls } from 'three/addons/controls/TransformControls.js';

    // 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
    const width = DOMEl.clientWidth;
    const height = DOMEl.clientHeight;

    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize( width, height );
    renderer.localClippingEnabled = true; 
    // 启用阴影
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 阴影类型
    DOMEl.appendChild( renderer.domElement );
    const scene = new THREE.Scene();
    renderer.setClearColor(0x000000);
    const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
    camera.position.set( 0, 80, 0 );
    camera.lookAt( 0, 0, 0 );
    
    // 添加一个立方体
    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);


    // 创建 TransformControls 控件并绑定到摄像机和渲染器的 DOM 元素
    const transformControls = new TransformControls(camera, renderer.domElement);
    scene.add(transformControls);

    // 将 TransformControls 附加到立方体上
    transformControls.attach(cube);

    // 添加事件监听器以响应控件的变化
    transformControls.addEventListener('change', () => renderer.render(scene, camera));

    // 设置 TransformControls 的模式,可以是 'translate'(平移)、'rotate'(旋转)、'scale'(缩放)
    transformControls.setMode('translate');
    
    // 监听 TransformControls 的事件
    transformControls.addEventListener('change', () => {
        console.log('Object is being transformed.');
        renderer.render(scene, camera);  // 实时更新渲染
    });

    transformControls.addEventListener('mouseDown', () => {
        console.log('Started transforming the object.');
    });

    transformControls.addEventListener('mouseUp', () => {
        console.log('Finished transforming the object.');
    });

    // 为了支持动态切换模式,监听键盘事件
    window.addEventListener('keydown', (event) => {
        switch (event.key) {
            case 'g': // 按 'g' 切换到平移模式
                transformControls.setMode('translate');
                break;
            case 'r': // 按 'r' 切换到旋转模式a
                transformControls.setMode('rotate');
                break;
            case 's': // 按 's' 切换到缩放模式
                transformControls.setMode('scale');
                break;
        }
    });
    function animate() {
        requestAnimationFrame(animate);
        // orbitControls.update(); // 更新 OrbitControls
        renderer.render(scene, camera);
    }
    animate();

事件

  • change 如果发生了任何类型的改变(对象或属性的改变)则触发该事件。 属性改变是单独的事件,你也可以为此添加单独的事件监听;该事件类型为"propertyname-changed"(“属性名称-changed”)。
  • mouseDown 如果指针(鼠标/触摸)为活动状态则触发该事件。
  • mouseUp 如果指针(鼠标/触摸)不再为活动状态则触发该事件。
  • objectChange 如果被控制的3D对象发生改变则触发该事件。

属性

  • axis : String 当前变换轴。
  • camera : Camera 渲染
  • 摄像机。
  • dragging : Boolean 当前是否正在拖动。只读属性。
  • mode : String 当前的变换模式。可能的值包括"translate"、"rotate" 和 "scale"。默认为translate。
  • rotationSnap : Number 默认情况下,3D对象是可以被连续旋转的。如果你将该值设为一个数值(弧度),则你将可以定义每次旋转3D对象时的步幅。 默认为null。
  • showX : Boolean x轴手柄是否显示。默认为true。
  • showY : Boolean y轴手柄是否显示。默认为true。
  • showZ : Boolean z轴手柄是否显示。默认为true。
  • size : Number size: 手柄UI的大小。 设置手柄UI的大小。
  • space : String 定义了在哪种坐标空间中进行变换。可能的值有"world" 和 "local"。默认为world。
  • translationSnap : Number 默认情况下,3D对象是可以被连续平移的。如果你将该值设为一个数值(世界单位),则你将可以定义每次平移3D对象时的步幅。 默认为null。

方法

  • attach ( object : Object3D ) : TransformControls object: 应当变换的3D对象。 设置应当变换的3D对象,并确保控制器UI是可见的。
  • detach () : TransformControls 从控制器中移除当前3D对象,并确保控制器UI是不可见的。
  • getHelper () : Object3D 返回控件的视觉表示。将辅助对象添加到场景中,以直观地变换附着的3D对象。
  • getRaycaster () : Raycaster 返回用于用户交互的 Raycaster 对象。 此对象在所有实例之间共享 变换控件。 如果您设置 TransformControls 的 .layers 属性,您还需要 使用匹配值设置 Raycaster 上的 .layers 属性,否则设置 TransformControls 不会按预期工作。
  • getMode () : String 返回变换模式。
  • reset () : undefined 将对象的位置、旋转和缩放重置为当前变换开始时的状态。
  • setMode ( mode : String ) : undefined mode: 变换模式。 设置变换模式。
  • setRotationSnap ( rotationSnap : Number ) : undefined rotationSnap: 旋转捕捉步幅。 设置旋转捕捉。
  • setSize ( size : Number ) : undefined size: 手柄UI的大小。 设置手柄UI的大小。
  • setSpace ( space : String ) : undefined space: 应用变换的坐标空间。 设置应用变换的坐标空间。
    "local":操作会基于对象的本地坐标系进行。例如,在旋转模式下,旋转会遵循对象自身的坐标轴方向。
    "world":操作会基于世界坐标系进行。此时,平移和旋转会相对于场景的全局坐标系进行,而不是对象的本地坐标。
    
    例:当一个立方体的中心点座标为 0,0,0  时 local 与 world 没有区别但是当标不为 0,0,0 时 local 是以立方体的中心点旋转或平移。
  • setTranslationSnap ( translationSnap : Number ) : undefined translationSnap: 平移捕捉步幅。 设置平移捕捉。