Three.js中基于DragControls的条件拖拽开关实现问题
解决Three.js中通过标志位控制DragControls激活/停用的问题
你的代码问题在于仅在初始化阶段根据drag_flag设置了一次DragControls的状态,点击按钮修改drag_flag后,并没有同步更新控件的激活状态,所以开关功能失效。
只需要修改change_drag_flag函数,在切换drag_flag的同时直接更新DragControls的状态即可,以下是修正后的完整代码:
修正后的JavaScript代码
var drag_flag = true; var drag_controls; // 提前声明,确保函数能访问到控件实例 function change_drag_flag(){ drag_flag = !drag_flag; // 切换标志位后同步更新控件状态 if(drag_flag){ drag_controls.activate(); drag_controls.enabled = true; } else { drag_controls.deactivate(); drag_controls.enabled = false; } } var objects = []; var scene = new THREE.Scene(); let box_geometry = new THREE.BoxGeometry(1, 1, 1); var material = new THREE.MeshPhongMaterial(); const box = new THREE.Mesh(box_geometry, material); objects.push(box); scene.add(box); var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(5, 5, 5); scene.add(spotLight); spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(-5, 5, 5); scene.add(spotLight); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.set(0.1, 4, 1); camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); drag_controls = new THREE.DragControls(objects, camera, renderer.domElement); // 初始化时设置初始状态(可选,DragControls默认处于激活状态) if(drag_flag){ drag_controls.activate(); drag_controls.enabled = true; } else { drag_controls.deactivate(); drag_controls.enabled = false; } // 添加渲染循环,确保场景持续更新(原代码缺少此部分,拖动后画面不会刷新) function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();
修正后的HTML代码
<button type="button" onclick="change_drag_flag()">Change Drag Flag</button> <script src="https://cdn.jsdelivr.net/npm/three@0.101.1/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.101.1/examples/js/controls/DragControls.js"></script>
关键修改说明
- 提前声明drag_controls变量:确保
change_drag_flag函数能访问到控件实例 - 同步更新控件状态:每次切换drag_flag后,立即调用activate/deactivate并设置enabled属性,保证控件状态与标志位一致
- 添加渲染循环:原代码仅渲染一次场景,拖动物体后画面不会更新,添加
animate函数使用requestAnimationFrame持续渲染,才能看到拖动效果
内容的提问来源于stack exchange,提问作者Bilal
相关产品推荐
相关产品推荐

