Skip to content

在Three.js中,MapControls是一种类似于地图导航的相机控件,它提供了一种直观的方式来控制相机的视角,实现类似百度地图的3D导航功能。以下是详细介绍如何使用MapControls的教程和示例代码。


探索MapControls:实现3D导航功能

MapControls简介

MapControls是一种相机控件,它允许用户通过鼠标操作来控制相机的视角,包括平移、旋转和缩放。这种控件非常适合实现3D地图或复杂场景的导航。

MapControls的操作方式

  • 平移:鼠标左键拖动
  • 旋转:鼠标右键拖动
  • 缩放:鼠标中键滚动

引入MapControls

在新版本的Three.js中,MapControls可以通过OrbitControls.js文件引入。

javascript
import { MapControls } from 'three/addons/controls/OrbitControls.js';

确保你的HTML文件中包含了正确的importmap配置。

html
<script type="importmap">
{
  "imports": {
    "three": "https://threejs.org/build/three.module.js",
    "three/addons/": "https://threejs.org/examples/jsm/"
  }
}
</script>

使用MapControls

创建MapControls实例时,需要传入相机对象和渲染器的DOM元素。

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

MapControls的本质

MapControls本质上是改变相机的参数,如位置属性.position和相机目标观察点。

示例代码:观察相机参数变化

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

禁止平移、缩放或旋转

可以通过设置MapControls的属性来禁止平移、缩放或旋转。

javascript
controls.enablePan = false; // 禁止平移
controls.enableZoom = false; // 禁止缩放
controls.enableRotate = false; // 禁止旋转

设置缩放范围

通过设置.minDistance.maxDistance属性,可以限制相机与观察目标点之间的距离,从而控制缩放范围。

javascript
controls.minDistance = 200; // 相机位置与观察目标点最小值
controls.maxDistance = 500; // 相机位置与观察目标点最大值

设置旋转范围

通过设置.minPolarAngle.maxPolarAngle属性,可以控制相机的上下旋转范围。通过设置.minAzimuthAngle.maxAzimuthAngle属性,可以控制左右的旋转范围。

javascript
controls.minPolarAngle = 0; // 上下旋转范围最小值
controls.maxPolarAngle = Math.PI / 2; // 上下旋转范围最大值

controls.minAzimuthAngle = -Math.PI / 2; // 左右旋转范围最小值
controls.maxAzimuthAngle = Math.PI / 2; // 左右旋转范围最大值

完整示例代码

以下是一个完整的示例,展示如何在Three.js中使用MapControls来控制相机。

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js MapControls Example</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script type="importmap">
    {
      "imports": {
        "three": "https://threejs.org/build/three.module.js",
        "three/addons/": "https://threejs.org/examples/jsm/"
      }
    }
    </script>
    <script type="module">
      import * as THREE from 'three';
      import { MapControls } from 'three/addons/controls/OrbitControls.js';

      const scene = new THREE.Scene();
      const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      const controls = new MapControls(camera, renderer.domElement);
      controls.target.set(0, 0, 0);

      const geometry = new THREE.BoxGeometry(100, 100, 100);
      const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
      const cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

      camera.position.set(0, 0, 5);

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

      // 禁止平移、缩放和旋转
      controls.enablePan = false;
      controls.enableZoom = false;
      controls.enableRotate = false;

      // 设置缩放范围
      controls.minDistance = 200;
      controls.maxDistance = 500;

      // 设置旋转范围
      controls.minPolarAngle = 0;
      controls.maxPolarAngle = Math.PI / 2;
      controls.minAzimuthAngle = -Math.PI / 2;
      controls.maxAzimuthAngle = Math.PI / 2;

      function render() {
          requestAnimationFrame(render);
          controls.update(); // 更新控制器
          renderer.render(scene, camera);
      }
      render();
    </script>
</body>
</html>

Theme by threelab