Three.js 中的 OrbitControls
是一个用于控制相机围绕目标旋转以及缩放、平移等操作的控制器。下面是它的详细讲解:
构造函数:
javascript
OrbitControls(object: Camera, domElement?: HTMLElement)
object
:THREE.Camera 实例,控制器将围绕此对象进行操作,例如相机。domElement
(可选):用于监听鼠标事件的 HTML 元素。如果未提供,则默认为document
。
属性:
-
enabled: boolean
- 控制器是否启用。
-
target: Vector3
- 控制相机围绕其旋转的目标点。
-
minDistance: number
- 缩放的最小距离。
-
maxDistance: number
- 缩放的最大距离。
-
minPolarAngle: number
- 极角的最小值。
-
maxPolarAngle: number
- 极角的最大值。
-
minAzimuthAngle: number
- 方位角的最小值。
-
maxAzimuthAngle: number
- 方位角的最大值。
-
enableDamping: boolean
- 是否启用阻尼以实现平滑移动。
-
dampingFactor: number
- 阻尼系数,控制平滑移动的速度。
-
enableZoom: boolean
- 是否启用缩放功能。
-
zoomSpeed: number
- 缩放速度。
-
enableRotate: boolean
- 是否启用旋转功能。
-
rotateSpeed: number
- 旋转速度。
-
enablePan: boolean
- 是否启用平移功能。
-
panSpeed: number
- 平移速度。
-
screenSpacePanning: boolean
- 是否启用屏幕空间平移。
-
keyPanSpeed: number
- 按键平移速度。
-
autoRotate: boolean
- 是否启用自动旋转。
-
autoRotateSpeed: number
- 自动旋转速度。
方法:
-
update(): void
- 更新控制器状态。
-
listenToKeyEvents(domElement: HTMLElement): void
- 监听键盘事件。
-
saveState(): void
- 保存当前控制器状态。
-
reset(): void
- 重置控制器状态为初始状态。
-
dispose(): void
- 清理控制器所占用的资源,释放内存。
示例:
javascript
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 创建相机
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建 OrbitControls 实例
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器属性
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.rotateSpeed = 0.5;
// 动画循环
function animate() {
requestAnimationFrame(animate);
controls.update(); // 更新控制器状态
renderer.render(scene, camera);
}
animate();
// 创建场景
js
function init() {
// 创建场景
scene = new THREE.Scene();
// 设置背景颜色
scene.background = new THREE.Color(0xcccccc);
// 添加雾效
scene.fog = new THREE.FogExp2(0xcccccc, 0.002);
// 创建渲染器
renderer = new THREE.WebGLRenderer({ antialias: true });
// 设置像素比率
renderer.setPixelRatio(window.devicePixelRatio);
// 设置渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器的 DOM 元素添加到文档中
document.body.appendChild(renderer.domElement);
// 创建相机
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
// 设置相机位置
camera.position.set(400, 200, 0);
// 控制器
controls = new OrbitControls(camera, renderer.domElement);
controls.listenToKeyEvents(window); // 可选,监听键盘事件
//controls.addEventListener( 'change', render ); // 仅在静态场景中调用此行 (即如果没有动画循环)
// 启用阻尼以实现平滑移动
controls.enableDamping = true;
// 设置阻尼系数
controls.dampingFactor = 0.05;
// 禁用屏幕空间平移
controls.screenSpacePanning = false;
// 设置缩放的最小距离
controls.minDistance = 100;
// 设置缩放的最大距离
controls.maxDistance = 500;
// 设置极角最大值
controls.maxPolarAngle = Math.PI / 2;
// 创建几何体和材质
const geometry = new THREE.ConeGeometry(10, 30, 4, 1);
const material = new THREE.MeshPhongMaterial({ color: 0xffffff, flatShading: true });
// 创建网格并随机添加到场景中
for (let i = 0; i < 500; i++) {
const mesh = new THREE.Mesh(geometry, material);
mesh.position.x = Math.random() * 1600 - 800;
mesh.position.y = 0;
mesh.position.z = Math.random() * 1600 - 800;
mesh.updateMatrix();
mesh.matrixAutoUpdate = false;
scene.add(mesh);
}
// 创建灯光并添加到场景中
const dirLight1 = new THREE.DirectionalLight(0xffffff, 3);
dirLight1.position.set(1, 1, 1);
scene.add(dirLight1);
const dirLight2 = new THREE.DirectionalLight(0x002288, 3);
dirLight2.position.set(-1, -1, -1);
scene.add(dirLight2);
const ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);
// 窗口大小调整时更新渲染器和相机
window.addEventListener('resize', onWindowResize);
}
// 窗口大小调整时更新渲染器和相机
js
function onWindowResize() {
// 更新相机的长宽比
camera.aspect = window.innerWidth / window.innerHeight;
// 更新相机的投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器的大小
renderer.setSize(window.innerWidth, window.innerHeight);
}
// 渲染场景
js
function animate() {
// 请求下一帧动画
requestAnimationFrame(animate);
// 更新控制器状态,仅在启用阻尼或自动旋转时才需要
controls.update();
// 渲染场景
render();
}
function render() {
// 使用渲染器将场景渲染到相机视角
renderer.render(scene, camera);
}