Skip to content

32. OrbitControls 的常用属性方法

Published:

OrbitControls 我们从开始到现在一直在用,但它很多属性方法都没用过。

这节我们就把这些常用的属性方法过一遍。

创建项目:

npx create-vite orbit-controls

image.png

进入项目,安装依赖:

npm install
npm install --save three
npm install --save-dev @types/three

改下 src/main.js

import './style.css';
import * as THREE from 'three';
import {
    OrbitControls
} from 'three/addons/controls/OrbitControls.js';

const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry(100, 100, 100);
const material = new THREE.MeshPhongMaterial({
  color: 'orange'
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

const directionLight = new THREE.DirectionalLight(0xffffff, 2);
directionLight.position.set(500, 400, 300);
scene.add(directionLight);

const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);

const width = window.innerWidth;
const height = window.innerHeight;

const helper = new THREE.AxesHelper(500);
scene.add(helper);

const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 10000);
camera.position.set(500, 600, 800);
camera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(width, height)

const controls = new OrbitControls(camera, renderer.domElement);

function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

render();

document.body.append(renderer.domElement);

创建 Scene、Light、Camera、Renderer。

改下 style.css

body {
  margin: 0;
}

跑一下:

npm run dev

image.png

image.png

OrbitControls

我们先来过一下 OrbitControls 的 api:

image.png

前面我们都是自己写的相机圆周运动,其实 OrbitControls 自带这个,开启 autoRotate,但要每帧调用下 update 方法:

const controls = new OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;

function render() {
    controls.update();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

2025-04-17 08.23.29.gif

默认转一周 30s,你可以把速度调成 10 倍,那就是一圈 3 秒

controls.autoRotateSpeed = 10.0;

2025-04-17 08.25.17.gif

默认是拖动是没有惯性的:

2025-04-17 08.26.07.gif

你可以开启惯性:

image.png

controls.enableDamping = true;

2025-04-17 08.26.56.gif

你还可以禁用旋转:

image.png

controls.enableRotate = false;

2025-04-17 08.31.57.gif

这时候不能拖动旋转,但可以右键平移,滚轮缩放。

你也可以禁用平移和缩放:

controls.enablePan = false;
controls.enableZoom  = false;

默认右键平移,左键拖动,滚轮缩放,你也可以自定义:

image.png

比如左键平移,右键旋转:

controls.mouseButtons = {
    RIGHT: THREE.MOUSE.ROTATE,
    LEFT: THREE.MOUSE.PAN
}

2025-04-17 08.36.02.gif

之前我们旋转相机的时候,经常能旋转到地面之下,其实这个也可以限制:

image.png

controls.maxPolarAngle  = Math.PI /2;

默认旋转范围是 0 到 Math.PI,我们改成一半:

2025-04-17 08.39.16.gif

这样就旋转不到地面之下了。

此外,我们还经常监听 change 事件来拿到实时的相机位置和焦点:

controls.addEventListener('change', () => {
  console.log(camera.position, controls.target);
})

相机位置是 camra.position 相机焦点是 controls.target

2025-04-17 08.46.36.gif

你可以取最后的相机位置和焦点来更新到代码里:

image.png

camera.position.set(447, 198, -112);
camera.lookAt(-373, -160, -257);

这样刷新页面看到的就是调好的位置和焦点了:

image.png

注意,这里要把 OrbitControls 注释掉才会生效,不然默认又把焦点调回到 0,0,0 了。

image.png

当然,你也可以同步设置 OrbitControls 为这个焦点:

image.png

controls.target.set(-373, -160, -257);

这样也可以。

2025-04-17 09.00.35.gif

案例代码上传了小册仓库

总结

这节我们过了一遍 OrbitControls 的常用属性方法。

可以开启 autoRotate 自动旋转,可以加上惯性 enableDamping,可以开启 rotate、zoom、pan,也可以限制 rotate 的范围 maxPolarAngle

我们经常监听 change 事件来可视化调节相机的位置和焦点,就是打印 camera.position 和 controls.target。

但是要注意 OrbitControls 默认会把焦点调回 0,0,0,调好之后要同步设置 camera.lookAt 和 controls.target.set

这些 OrbitControls 的属性方法都是经常会用到的。

评论