three ArcballControls 弧球控制器

247 阅读6分钟

ArcballControls 是 Three.js 中的一种控制器,允许用户通过拖动鼠标来旋转相机或对象,从而实现一个类似于球体的旋转效果。它常用于需要自由旋转视角的三维场景,特别是在展示复杂模型时。

ArcballControls 有二十个属性十一个方法三个事件

ArcballControls( camera : Camera, domElement : HTMLDOMElement, scene : Scene ) camera:(必填)要控制的相机。相机不能是另一个对象的子对象,除非该对象是场景本身。 domElement: 用于事件侦听器的 HTML 元素。(可选) scene: 相机渲染的场景。如果未给出,则小控件无法显示。(可选)

    const controls = new ArcballControls(camera, renderer.domElement);
    // 监听 change 事件
    controls.addEventListener('change', () => {
        // 在每次控制器状态变化时执行的逻辑
        console.log('Camera or controls changed');
        renderer.render(scene, camera); // 更新渲染
    });
    // 渲染循环
    function animate() {
        requestAnimationFrame(animate);
        controls.update(); // 更新控制器
        renderer.render(scene, camera);
    }
    animate();

事件

  • change 当相机被小控件改变时触发。
  • start 当交互开始时触发。
  • end 当交互完成时触发。

属性

  • adjustNearFar : Boolean 如果为 true,则每次执行缩放时都会调整相机的近端和远端值,尝试保持初始近端和远端值给出的相同可见部分(仅限 PerspectiveCamera )。默认为 false。
  • camera : Camera 被控制的摄像机。
  • cursorZoom : Boolean 设置为 true 以使缩放变为光标居中。 在 ArcballControls 中,cursorZoom 是一个可选的布尔属性,其作用是控制缩放时是否使用光标位置。 基于wheel 事件
  • dampingFactor : Float 设置为 .enableAnimations 为true 时使用的阻尼惯性。取值范围[0-1]主要控制转动场景效果
    0 表示没有阻尼,运动是瞬时的,可能导致相机的运动感觉很生硬。
    1 表示最大阻尼,相机运动会非常缓慢,提供更平滑的体验,但可能会导致响应较慢。
  • enableAnimations : Boolean 设置为 true 以启用旋转(阻尼)和聚焦操作的动画。默认为 true。
  • enableGrid : Boolean 设置为 true 时,执行平移操作时将出现网格(仅限桌面交互)。默认为 false。
  • enablePan : Boolean 启用或禁用相机平移。默认为 true。
    // 设置相机初始位置
    camera.position.set(0, 5, 10);
    // 处理键盘事件
    const keys = {};
    window.addEventListener('keydown', (event) => {
        keys[event.code] = true;
    });
    window.addEventListener('keyup', (event) => {
        keys[event.code] = false;
    });
    // 渲染循环
    function animate() {
        requestAnimationFrame(animate);
        // 检测键盘输入来平移相机
        const moveSpeed = 0.1; // 平移速度
        if (keys['KeyW']) { // 向前
            camera.position.z -= moveSpeed;
        }
        if (keys['KeyS']) { // 向后
            camera.position.z += moveSpeed;
        }
        if (keys['KeyA']) { // 向左
            camera.position.x -= moveSpeed;
        }
        if (keys['KeyD']) { // 向右
            camera.position.x += moveSpeed;
        }
        // 更新控制器和渲染场景
        controls.update(); // 如果使用了控制器
        renderer.render(scene, camera);
    }
    animate();
  • enableRotate : Boolean 启用或禁用相机旋转。默认为 true。enableRotate 属性用于控制相机的旋转功能。当启用此属性时,用户可以通过拖动鼠标来旋转相机,以查看场景中的对象。
  • enableZoom : Boolean 启用或禁用相机变焦。enableZoom 属性用于控制相机的缩放功能。当启用此属性时,用户可以通过鼠标滚轮或其他输入方式来缩放相机,从而放大或缩小场景中的对象。
  • focusAnimationTime : Float 焦点动画的持续时间。focusAnimationTime 属性用于设置在相机对焦时的动画持续时间,以平滑地过渡到目标位置。当用户触发对焦操作时,相机会在这个设定的时间内平滑移动到目标位置,而不是瞬间跳转,这样可以提升用户的体验。
  • maxDistance : Float 最大移动距离(仅限 PerspectiveCamera)。默认为无穷大。
  • maxZoom : Float 最大缩放值(仅限 OrthographicCamera )。默认为无穷大。
  • radiusFactor : Float 小控件相对于屏幕宽度和高度的大小。默认值为 0.67。radiusFactor 属性用于控制 Arcball 控件中相机的半径因子,它决定了相机围绕目标旋转时的距离比例。通过调整该属性,您可以改变相机与目标对象之间的距离,从而影响用户在操作时的视角和体验。
  • rotateSpeed : Float 旋转速度。默认值为 1。
  • scaleFactor : Float 执行缩放操作时使用的缩放因子。
  • scene : Scene 相机渲染的场景。
  • wMax : Float 旋转动画开始时允许的最大角速度。

方法

  • activateGizmos ( isActive : Boolean ) : undefined 使小控件或多或少可见。
启用辅助工具: 当 isActive 设置为 true 时,场景中的辅助工具(如轴、平面等)将被显示出来,方便用户进行操作。
禁用辅助工具: 当 isActive 设置为 false 时,所有的辅助工具将被隐藏,提供更清晰的视图,用户只关注场景中的对象。
  • copyState () : undefined 将当前状态复制到剪贴板(作为可读的 JSON 文本)。
  • pasteState () : undefined 从剪贴板设置控件状态,假设剪贴板存储从 .copyState 保存的 JSON 文本。
  • reset () : undefined 将控件重置为上次调用 .saveState 时的状态或初始状态。
  • saveState () : undefined 保存控件的当前状态。稍后可以使用 .reset 恢复。
  • setCamera ( camera : Camera ) : undefined 设置要控制的摄像机。必须调用才能设置要控制的新摄像机。
  • setGizmosVisible ( value : Boolean ) : undefined 设置小控件的可见属性。
  • setTbRadius ( value : Float ) : undefined 更新 radiusFactor 值,重新绘制小控件并发送 changeEvent 让可视化更新。
  • setMouseAction ( operation : String, mouse, key ) : Boolean 通过指定要执行的操作和鼠标/按键组合来设置新的鼠标操作。如果发生冲突,则替换现有的。 操作可以指定为 'ROTATE'、'PAN'、'FOV' 或 'ZOOM'。 鼠标输入可以指定为鼠标按钮 0、1、2 或 'WHEEL'。 键盘修饰符可以指定为 'CTRL'、'SHIFT' 或 null(如果不再需要)
  • unsetMouseAction ( mouse, key ) : Boolean 通过指定 鼠标/按键 组合来删除鼠标操作。 鼠标输入可以指定为鼠标按钮 0、1、2 或 'WHEEL'。 键盘修饰符可以指定为 'CTRL'、'SHIFT' 或 null(如果不再需要) 。
  • getRaycaster () : Raycaster 返回用于用户交互的 Raycaster 对象。如果设置了 ArcballControls 的 .layers 属性,您还需要使用匹配的值设置 [page:Raycaster.layers .layers] 的 Raycaster 属性,否则 ArcballControls 将无法按预期工作。
// 创建 ArcballControls
const controls = new ArcballControls(camera, renderer.domElement, scene);

// 添加场景中的对象
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 监听鼠标点击事件
window.addEventListener('click', (event) => {
    // 获取 Raycaster
    const raycaster = controls.getRaycaster();
    
    // 计算鼠标在标准设备坐标中的位置 (-1到1)
    const mouse = new THREE.Vector2();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // 更新 Raycaster
    raycaster.setFromCamera(mouse, camera);

    // 计算与场景中物体的交集
    const intersects = raycaster.intersectObjects(scene.children);

    // 如果有物体被点击
    if (intersects.length > 0) {
        console.log('Clicked on:', intersects[0].object); // 输出被点击的物体
        // 可以在这里添加交互逻辑,比如改变颜色或执行其他操作
        intersects[0].object.material.color.set(0xff0000); // 改变颜色为红色
    }
});