You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TransformControls的translate模式下仅保留箭头控件?

问题描述

目前TransformControls基本满足我的需求,但控件中存在额外元素,比如物体远处的箭头和一些方块。请问是否可以关闭这些元素,仅保留translate模式下的箭头控件?

TransformControls当前效果
期望效果

最小复现代码
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';

const boxGeometry = new THREE.BoxGeometry();
const theeBoxMaterial = new THREE.MeshBasicMaterial({ color: 0x00FF00 });
const theeBox = new THREE.Mesh(boxGeometry, theeBoxMaterial);
const renderer = new THREE.WebGLRenderer();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
);

const gridHelper = new THREE.GridHelper(30);
scene.add(gridHelper);

scene.add(theeBox);

const orbitControls = new OrbitControls(camera, renderer.domElement);
const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.attach(theeBox);
transformControls.setMode('translate')
scene.add(transformControls);

renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

camera.position.set(50, 30, 20);
camera.lookAt(0, 0, 0);

const rayCaster = new THREE.Raycaster();
const mousePos = new THREE.Vector2();

let isDragging = false;

transformControls.addEventListener('dragging-changed', function (event) {
    orbitControls.enabled = !event.value;
    isDragging = event.value;
});

function animateTheeBox() {
    if (!isDragging && !orbitControls.enabled) {
        rayCaster.setFromCamera(mousePos, camera);
        const intersect = rayCaster.intersectObjects([theeBox]);

        if (intersect.length === 0) {
            const moveSpeed = 0.1;
            camera.position.x += (mousePos.x - 0.5) * moveSpeed;
            camera.position.y += (mousePos.y - 0.5) * moveSpeed;
            camera.lookAt(0, 0, 0);
        }
    }

    renderer.render(scene, camera);
}

renderer.setAnimationLoop(animateTheeBox);
解决方案

可以通过TransformControls的配置属性或直接控制子对象可见性,隐藏不需要的元素,仅保留translate模式下的轴箭头:

方法一:使用官方属性配置

利用TransformControls提供的公开属性,直接关闭冗余控件:

const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.attach(theeBox);
transformControls.setMode('translate');

// 隐藏平面拖拽控件
transformControls.showTranslatePlane = false;
// 确保使用局部空间,避免显示全局轴箭头
transformControls.space = 'local';
// 强制保留三个轴的箭头显示
transformControls.showTranslateX = true;
transformControls.showTranslateY = true;
transformControls.showTranslateZ = true;

scene.add(transformControls);

方法二:遍历子对象精准隐藏

如果官方属性无法覆盖需求,可直接遍历控件的子对象,按名称隐藏指定元素:

const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.attach(theeBox);
transformControls.setMode('translate');

// 遍历并隐藏不需要的控件元素
transformControls.traverse((child) => {
    // 隐藏中心拖拽方块和平面拖拽控件
    if (child.name.includes('TranslateCenter') || child.name.includes('TranslatePlane')) {
        child.visible = false;
    }
    // 隐藏全局轴箭头(若存在)
    if (child.name === 'WorldAxes') {
        child.visible = false;
    }
});

scene.add(transformControls);

以上两种方法都能实现仅保留translate模式下三个轴箭头的效果。


内容的提问来源于stack exchange,提问作者RickyLo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:56:11