在threejs开发中,不可避免的需要对三维场景进行交互,例如对模型进行旋转,缩放,平移等操作。接下来,我们就聊一聊如何进行三维场景的交互。

控制的对象是谁?

在三维的世界中,如果想达到场景的TRS(translate、rotate、scale)操作,我们其实有两种办法来做到。一种是对模型本身进行TRS操作,通过改变模型的属性,达到视觉上的效果。第二种是对相机进行操作,把相机拉远模型自然缩小了,把相机移动,模型自然就向相反方向移动了。

两种方式各自有各自的特点和使用场景。操作模型,我们可以控制每个模型的TRS,比如在一个家装场景中,我们要对某个家具进行拖动,缩放。操作相机,我们可以对整个场景进行操作,比如拉远相机,查看场景全局外观。两种方式经常也会配合在一起使用。

操作模型

操作模型,首先,选中需要操作的模型。这部分需要,用到我们之前介绍过的拾取操作,首先拾取都某个三维模型,作为选中对象。然后我们才能对选中对象进行操作。第二部分是鼠标及手势的输入及判断。例如我们需要使用鼠标的滚轮触发缩放操作,或者触屏双指进行缩放操作。最后,就是进行模型的属性修改,在threejs中一般使用position,rotate,scale来达到修改模型外观的目的。

我们从最简单的模型缩放来具体讲讲如何实现。

缩放

renderer.domElement.addEventListener("mousewheel", (event) => {

var scaleFactor= 0.001; //鼠标滚轮控制的缩放强度系数

var scale = 1 + event.wheelDelta * scaleFactor; //缩放倍数

cube.scale.multiplyScalar(scale)

})

平移

对于平移来说,我们需要设置一个参考面,让这个模型在这个参考面上进行平移。一般来说我们常见的平移方式有固定参考面,比如地面、墙面。除此以外还有就是相机朝向的参考面。

如图所示,我们以mesh的中心点为面上的一个点,然后以相机的朝向为法向量,可以创建一个平面。整个鼠标的拖动都应该在这个面上。

let dragTarget = null; //拖拽对象

let raycaster = new THREE.Raycaster(); //射线

let mouse = new THREE.Vector2(); //鼠标位置

let hit = new THREE.Vector3(); //射线在参考面上的拾取点

let plane = new THREE.Plane(); //拖拽参考面

plane.setFromNormalAndCoplanarPoint(camera.getWorldDirection(), cube.position);

//let helper = new THREE.PlaneHelper( plane, 50, 0xffff00 ); //拖拽参考面的可视化帮助类

//scene.add( helper );//添加拖拽参考面的可视化帮助类到场景

renderer.domElement.addEventListener("mousedown", (event) => {

mouse.x = (event.clientX / window.innerWidth) * 2 - 1;

mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

raycaster.setFromCamera(mouse, camera);

let intersects = raycaster.intersectObjects([cube], true);

if (intersects.length > 0) {

dragTarget = intersects[0].object;

}

})

renderer.domElement.addEventListener("mousemove", (event) => {

if (dragTarget) {

mouse.x = (event.clientX / window.innerWidth) * 2 - 1;

mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

raycaster.setFromCamera(mouse, camera);

raycaster.ray.intersectPlane(plane, hit);

if (hit) {

cube.position.copy(hit);

console.log(hit)

}

}

})

renderer.domElement.addEventListener("mouseup", (event) => {

dragTarget = null;

})

旋转

一般来说,我们旋转物体都是沿着某个轴的,比如Y轴。我们以鼠标X移动的增量作为参数,沿着模型Y轴方向旋转。

let lastX = null;

renderer.domElement.addEventListener("mousedown", (event) => {

lastX = event.clientX;

})

renderer.domElement.addEventListener("mousemove", (event) => {

if (lastX) {

let delta = event.clientX - lastX

cube.rotateY(delta * 0.01)

lastX = event.clientX;

}

})

renderer.domElement.addEventListener("mouseup", (event) => {

lastX = null;

})

操作相机

threejs为我们提供了一系列的相机操作控件。对于相机控制,最常用的就是OrbitControls控件(一般放在threejs的examples/jsm/controls/OrbitControls.js)。使用起来也比较简单。只需importy引入文件,然后new出一个控件即可。这里注意就是如果copy文件到项目目录,需要手动修改js文件中关于threejs的引用,因为控件中的threejs是引用的是编译出来的文件相对地址,不是通过npm安装的地址。

import {

OrbitControls

} from '../lib/controls/OrbitControls'

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

控件提供了鼠标左键旋转,右键平移,滚轮缩放的功能,并且支持手势操作。

以上就是对threejs中三维场景操作控制的说明,后续我们将继续讲讲如何在3d场景中加入一些动画。

threejs 加载两个场景_threejs中的三维场景操作相关推荐

  1. threejs 加载两个场景_three.js 场景切换

    用6个面组成的立方体作为场景图,发现会出现变形的现象,css3DRenderer 不会变形,但是不方便增加文字,最后采用scene的背景作为场景,背景是用cubeTextureLoader()加载的. ...

  2. Spring mvc 启动配置文件加载两遍问题

    问题描述 在使用spring mvc 启动的时候,用到了一个在程序启动时加载的配置方法init-method="initLoad",并启动多线程来做数据同步,但是在程序启动之后发现 ...

  3. unity3d如何获知场景中需要加载的数据_游戏中遮挡剔除方案总结

    这是侑虎科技第507篇文章,感谢作者FrankZhou供稿.欢迎转发分享,未经作者授权请勿转载.如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨.(QQ群:793972859) 作者主页:htt ...

  4. WKWebView Safari调试、JS互调、加载进度条、JS中alert、confirm、prompt

    主要内容 Safari调试 swift/OC与JS互调 增加加载进度条 支持JS中alert.confirm.prompt Safari调试 设置 -> safari --> 高级,开启J ...

  5. 利用Visual Studio Project自动将数据加载到SQL Server数据库中

    介绍 (Introduction) A few months back, I encountered an interesting challenge at a client site. For th ...

  6. java懒加载注解_在springboot中实现个别bean懒加载的操作

    懒加载---就是我们在spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中. @Lazy 在需要懒加载的bean上加上@Lazy ...

  7. ThreeJS加载geojson数据实现3D地图

    ThreeJS加载geojson数据实现3D地图,主要通过借助geojson地理信息数据转摩托尔坐标实现,中间借助了d3.js的地图处理方法,最后通过threejs渲染到页面上: 通过平台获取GeoJ ...

  8. 【MFC】动态加载Picture Control控件中的图片

    [MFC]动态加载Picture Control控件中的图片 前言 方法1:CBrush 方法2:SetBitmap 参考链接 方法3:重写MyPictureControl 前言 在MFC窗体中,我们 ...

  9. jsp页面加载的时候,从后台获取数据,页面加载完成之后,下拉列表中已经有值

    在jsp中,我们经常会遇到这种情况:当页面加载完成之后,下拉列表中已经有数据,这是怎么实现的呢? 下面作以详解: 1.<body οnlοad="fun()">:在js ...

最新文章

  1. 变量的定义 声明和初始化和static
  2. mysql 函数重载_C#方法重载(函数重载)
  3. 三层架构与四大天王之——查
  4. SqlSugar与Fluent NHibernate的性能测试对比
  5. ArcSDE初学者需要弄清楚的几个问题(转载)
  6. xajax中的中文乱码问题
  7. 在MFC中显示Jpg格式图片的简单实现方法
  8. grub配置文件丢失的解决方法
  9. Kafka必须掌握的核心技术:简述Java线程池的作用和实现方式
  10. 内核移植(4)移植yaffs文件系统
  11. python 菜鸟-Python 列表(List)
  12. C/C++获取文件大小
  13. linux 联合编译,在Linux上编译UEFI SDK 2018/OVMF的方法
  14. 10. zf workflow
  15. SpringCloud 之客户端负载均衡策略
  16. [已解决]安装MPICH2(x64)时显示需要安装NET FRAMEWORK 2.0.50727
  17. ORACLE 中通过证件号码获取性别
  18. .pth.tar文件
  19. c语言互质欧拉函数,互质与欧拉函数
  20. 第2课计算机的发展教学反思,信息技术课教学反思2

热门文章

  1. 微软确认5月2日召开新品发布会 8天后就是Build 2017大会
  2. ASP.NET Core 导入导出Excel xlsx 文件
  3. .NET HttpClient的缺陷和文档错误让开发人员倍感沮丧
  4. vs使用ado连接oracle,在VS环境下以ADO方式操作Oracle数据库
  5. Android单击、长按获取当前触点坐标下(TextView)文字字符
  6. 利用浏览器调试功能 计算 百度网盘 文件数量
  7. 【ArcGIS遇上Python】使用add-in向导开发ArcGIS插件(1):add-in工具介绍及安装
  8. 【ArcGIS遇上Python】ArcGIS python计算长时间序列多个栅格数据的平均值
  9. C#趣味程序---理财高手
  10. linux c之fdopen(int fd, const char *type)使用总结