Three.js 中的 MapControls
是一个用于控制摄像机在地图中移动和缩放的控制器。它的构造函数以及主要的方法的入参和出参如下:
构造函数:
MapControls(camera: Camera, domElement?: HTMLElement)
camera
:THREE.Camera 实例,控制器将用于控制该相机。domElement
(可选):用于监听鼠标事件的 HTML 元素。如果未提供,则默认为document
。
主要方法:
-
update()
- 无入参
- 无返回值
- 作用:更新控制器状态,通常在动画循环中调用。
示例:
import * as THREE from 'three';
import { MapControls } from 'three/examples/jsm/controls/MapControls.js';
// 创建相机
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 200, -400);
// 创建地图控制器,并绑定到相机上
const controls = new MapControls(camera);
// 获取用于渲染的 HTML 元素
const rendererContainer = document.getElementById('renderer-container');
// 创建 WebGL 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染器的 DOM 元素添加到页面中
rendererContainer.appendChild(renderer.domElement);
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 更新地图控制器状态
controls.update();
// 渲染场景
renderer.render(scene, camera);
}
// 启动动画循环
animate();
在这个示例中,我们创建了一个 MapControls
实例,将其绑定到了一个相机上,并在动画循环中不断更新控制器状态以实现交互。
// 导入 MapControls
import * as THREE from 'three'; // 导入 three.js 库
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; // 导入 GUI 库
import { MapControls } from 'three/addons/controls/MapControls.js'; // 导入 MapControls
let camera, controls, scene, renderer; // 声明变量
init(); // 初始化场景
//render(); // 使用下一行的代码进行动画循环 (requestAnimationFrame) 时请删除此行
animate(); // 启动动画循环
// 初始化场景
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 } ); // 创建 WebGL 渲染器
renderer.setPixelRatio( window.devicePixelRatio ); // 设置像素比率
renderer.setSize( window.innerWidth, window.innerHeight ); // 设置渲染器尺寸
document.body.appendChild( renderer.domElement ); // 将渲染器附加到文档主体
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 ); // 创建相机
camera.position.set( 0, 200, - 400 ); // 设置相机位置
// 控制器
controls = new MapControls( camera, renderer.domElement ); // 创建地图控制器
//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.BoxGeometry(); // 创建立方体几何体
geometry.translate( 0, 0.5, 0 ); // 平移几何体
const material = new THREE.MeshPhongMaterial( { color: 0xeeeeee, flatShading: true } ); // 创建材质
for ( let i = 0; i < 500; i ++ ) {
const mesh = new THREE.Mesh( geometry, material ); // 创建网格
mesh.position.x = Math.random() * 1600 - 800; // 随机 x 位置
mesh.position.y = 0; // 设置 y 位置
mesh.position.z = Math.random() * 1600 - 800; // 随机 z 位置
mesh.scale.x = 20; // 设置 x 缩放
mesh.scale.y = Math.random() * 80 + 10; // 随机 y 缩放
mesh.scale.z = 20; // 设置 z 缩放
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 ); // 添加窗口大小调整事件监听
const gui = new GUI(); // 创建 GUI
gui.add( controls, 'zoomToCursor' ); // 添加缩放到光标控制到 GUI
gui.add( controls, 'screenSpacePanning' ); // 添加屏幕空间平移控制到 GUI
}
// 相应式更新渲染器尺寸
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight; // 更新相机长宽比
camera.updateProjectionMatrix(); // 更新相机投影矩阵
renderer.setSize( window.innerWidth, window.innerHeight ); // 更新渲染器尺寸
}
// 请求动画帧
function animate() {
requestAnimationFrame( animate ); // 请求动画帧
controls.update(); // 更新控制器
render(); // 渲染场景
}
// 渲染场景
function render() {
renderer.render( scene, camera ); // 渲染场景
}