Three.js学习4:添加轨道控制器

 -----------------------------华丽的分割线---------------------

相关代码均已上传到 gitee 中:myThree: 学习 Three.js ,努力加油~!

Gitee 静态演示地址:Three JS 演示页面

 -----------------------------华丽的分割线---------------------

一、轨道控制器

拍摄画面的时候,为了保持镜头的稳定,并且能从多方位拍摄画面,往往会用到轨道(Orbit)

轨道控制器(Orbit controls)可以使得相机围绕目标进行轨道运动。

在 Three.js 里,轨道控制器可以通过鼠标左右键、鼠标滚动控制画面的上下左右旋转、移动、缩放,可以从多个角度观测目标物体。其效果类似 Three.js 提供的官方编辑器一样。

官方编辑器允许用鼠标左右键控制画面的旋转和移动。

http://localhost:9000/editor/

二、导入轨道控制器组件

轨道控制器(Orbit controls) 是一个附加组件,必须显式导入。

1. 拷贝附加组件文件

Three.js附加组件,包括轨道控制器、模型加载器等,都是放在 example/jsm 文件夹下的。因此,首先要把 jsm 文件夹的东西都拷贝到项目文件夹中。

我这里是拷贝到 js 目录下。

吐槽下:害的我找了好久,半天不知道怎么导入。

2. 页面添加 importmap 代码

<script type="importmap">
    {
        "imports": {
            "three" : "./js/three.module.min.js",
            "three/addons/": "./js/jsm/"
        }
    }
</script>

 来自 MDN:

导入映射(import map)是一个 JSON 对象,其允许开发者在导入 JavaScript 模块时,控制浏览器如何解析模块标识符。它提供了在 import 语句或 import() 运算符 (en-US)中用作模块标识符的文本,其会在解析标识符时与要替换的文本之间建立映射。JSON 对象必须符合导入映射 JSON 表示格式

一般我们在项目中导入模块,会调用require方法,或者使用import语句。导入的模块通常使用 npm 之类的包管理器进行管理。

但是,如果不用 npm 怎么管理模块?

import map就提供了一种支持,让我们可以直接在页面上管理模块,不需要通过 npm 之类的工具。

在我们的 JS 文件里添加轨道控制器附加组件导入代码。

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

 注意映射的对应关系:

三、轨道控制器对象

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

两个参数:

  • 相机对象:(必须)将要被控制的相机。该相机不允许是其他任何对象的子级,除非该对象是场景自身。

  • domElement: 用于事件监听的HTML元素。一般用渲染器DOM对象,也就是 canvas 标签。

更多的内容翻看官方文档,这里只罗列感觉常用的。

1. 常用属性

controls.enableDamping = true;  // 启用阻尼效果。必须应用动画。
controls.dampingFactor = 0.01;  // 设置阻尼值
controls.autoRotate = true;     // 自动旋转。必须应用动画。
controls.autoRotateSpeed = 1;   // 自动旋转速度

controls.minDistance = 5;   // 相机移动位置。用于透视相机 PerspectiveCamera
controls.maxDistance = 20;

controls.minZoom = 0.5;    // 最小、放大缩放比例。用于正交相机 OrthographicCamera
controls.maxZoom = 2;   

2. 启用键盘控制

// 增加了键盘控制
// 当使用键盘按键的时候,相机平移的速度有多快。默认值为每次按下按键时平移7像素。
controls.keyPanSpeed = 7
// 这一对象包含了用于控制相机平移的按键代码的引用。默认值为4个箭头(方向)键。
controls.keys = {
  LEFT: 'ArrowLeft', //left arrow
  UP: 'ArrowUp', // up arrow
  RIGHT: 'ArrowRight', // right arrow
  BOTTOM: 'ArrowDown' // down arrow
}

// 添加键盘事件监听。只有添加了键盘事件监听,上下左右键才能控制轨道
controls.listenToKeyEvents( window );

controls.stopListenToKeyEvents();  // 取消键盘事件监听

3. 动画更新

// 更新控制器。必须在摄像机的变换发生任何手动改变后调用
// 或如果.autoRotate或.enableDamping被设置时,在update循环里调用。
controls.update();

function animateFun(){
    
    controls.update();   // 现在动画里更新控制器
    // 渲染
    renderer.render( scene, camera);
    requestAnimationFrame(animateFun);
}
animateFun()

4. 事件

  • change:当摄像机被组件改变时触发。

  • start:初始化交互时触发。

  • end:当交互结束时触发。

// 添加 change 事件
controls.addEventListener("change",function(){
    console.info("change");
});

四、完整代码

在本人博文 Three.js学习3:第一个Three.js页面-CSDN博客 的基础上,修改代码。

HTML:

<!-- importmap 必须有 -->
<script type="importmap">
    {
        "imports": {
            "three" : "./js/three.module.min.js",
            "three/addons/": "./js/jsm/"
        }
    }
</script>
<script src="js/myjs.js" type="module"></script>

JS:

import  * as THREE  from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xEEEEEE);  // 设置场景背景色

// 物体:包含几何形 geometry 和 材质(皮肤) meterial 两部分
const geometry = new THREE.BoxGeometry(1,1,1);  // 立方体
const meterial = new THREE.MeshBasicMaterial({  
    color: "#ff0000"
});
const mesh = new THREE.Mesh( geometry, meterial);
scene.add( mesh );              // 添加物体到场景中

// 相机
const camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 100);
camera.position.set(0,0,10);    // 修改相机位置
camera.lookAt( mesh.position ); // 相机镜头盯着物体
scene.add( camera );            // 添加相机到场景中

// 添加网格线
const grid = new THREE.GridHelper( 10, 10 );
scene.add( grid );

// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );   // 设置渲染器(canvas标签)大小
document.body.appendChild( renderer.domElement );            // 添加渲染器(canvas标签)到页面中

// 轨道控制器
const controls = new OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;  // 启用阻尼效果。必须应用动画。
controls.dampingFactor = 0.01;  // 设置阻尼值
controls.autoRotate = true;     // 自动旋转。必须应用动画。
controls.autoRotateSpeed = 1;   // 自动旋转速度

controls.minDistance = 5;   // 最小,最大缩放比例。用于透视相机 PerspectiveCamera
controls.maxDistance = 20;

// 添加键盘事件监听。键盘按下的速度和按键,采用默认值。只有添加了键盘事件监听,上下左右键才能控制轨道
controls.listenToKeyEvents( window );

// 更新控制器
controls.update();

function animateFun(){
    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.01;
    controls.update();   // 现在动画里更新控制器
    // 渲染
    renderer.render( scene, camera);
    requestAnimationFrame(animateFun);
}
animateFun();

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值