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


最小复现代码
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
相关产品推荐
相关产品推荐

