当前位置: 首页 > news >正文

Threejs之光线投射Raycaster交互

这里写目录标题

  • 前言
  • 一、前置准备
    • 1.1 代码
    • 1.2 效果
  • 二、添加交互事件
    • 2.1 代码
    • 2.2 效果
  • 三、完整代码

前言

基于上篇文章Threejs之光线投射Raycaster我们知道了光线投射的基础用法,在本届我们将使用光线投射进行鼠标交互事件

一、前置准备

1.1 代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>html,body {margin: 0;padding: 0;width: 100%;height: 100%;}</style>
</head><body><script type="module">// 倒入轨道控制器import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'import * as THREE from "three";// 创建场景const scene = new THREE.Scene();// 创建相机const camera = new THREE.PerspectiveCamera( // 透视相机45, // 视角 角度数window.innerWidth / window.innerHeight, // 宽高比 占据屏幕0.1, // 近平面(相机最近能看到物体)1000, // 远平面(相机最远能看到物体));camera.position.set(0, 2, 20);// camera.lookAt(0, 0, 0);// 创建渲染器const renderer = new THREE.WebGLRenderer({antialias: true, // 抗锯齿});// 设置渲染器宽高renderer.setSize(window.innerWidth, window.innerHeight)// renderer(渲染器)的dom元素添加到我们的HTML文档中document.body.appendChild(renderer.domElement)// 开启坐标轴辅助器const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);const geometry = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), new THREE.MeshBasicMaterial({color: 0xff0000}));const geometry1 = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), new THREE.MeshBasicMaterial({color: 0xff0000}));const geometry2 = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), new THREE.MeshBasicMaterial({color: 0xff0000}));geometry1.position.x = 3;geometry2.position.x = -3;scene.add(geometry, geometry1, geometry2);// 控制器const control = new OrbitControls(camera, renderer.domElement);// 开启阻尼惯性,默认值为0.05control.enableDamping = true;// 渲染循环动画function animate() {// 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)requestAnimationFrame(animate);// 更新控制器。如果没在动画里加上,那必须在摄像机的变换发生任何手动改变后调用control.update();renderer.render(scene, camera);};// 执行动画animate();</script>
</body>
</html>

1.2 效果

在这里插入图片描述
在这里插入图片描述
可以看到我们在场景中放了三个球,并且设置了坐标轴辅助线。


二、添加交互事件

2.1 代码

添加鼠标交互事件,在鼠标点下去的时候我们去发射一束射线,让与之交互的物体做出一些改变,例如改变物体颜色,添加如下代码:

        // 表示2D vector(二维向量)的类const mouse = new THREE.Vector2();let geometryArr = [geometry, geometry1, geometry2];const raycaster = new THREE.Raycaster();// 监听鼠标点击事件window.addEventListener("mousedown", (event) => {// 转换为一个位于二维空间中的点,在标准化设备坐标中鼠标的二维坐标 —— X分量与Y分量应当在-1到1之间mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;console.log(mouse.x, mouse.y);// 使用一个新的原点和方向来更新射线raycaster.setFromCamera(mouse, camera);// 每次点击循环设置物体初始颜色,如不设置会导致点击物体后颜色变后不能再变for(const geometry of geometryArr) {geometry.material.color.set(0xff0000);}// 相交的物体变色const itgeometrys = raycaster.intersectObjects(geometryArr);for(const itgeometry of itgeometrys) {itgeometry.object.material.color.set(0xcc33f4);}})

2.2 效果

请添加图片描述
可以看到我们已经完成了简单的物体交互。不要小瞧了光线投射,在我们与物体交互中起来很大的作用。


三、完整代码

最后给出本届完整代码,如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>html,body {margin: 0;padding: 0;width: 100%;height: 100%;}</style>
</head><body><script type="module">// 倒入轨道控制器import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'import * as THREE from "three";// 创建场景const scene = new THREE.Scene();// 创建相机const camera = new THREE.PerspectiveCamera( // 透视相机45, // 视角 角度数window.innerWidth / window.innerHeight, // 宽高比 占据屏幕0.1, // 近平面(相机最近能看到物体)1000, // 远平面(相机最远能看到物体));camera.position.set(0, 2, 20);// camera.lookAt(0, 0, 0);// 创建渲染器const renderer = new THREE.WebGLRenderer({antialias: true, // 抗锯齿});// 设置渲染器宽高renderer.setSize(window.innerWidth, window.innerHeight)// renderer(渲染器)的dom元素添加到我们的HTML文档中document.body.appendChild(renderer.domElement)// 开启坐标轴辅助器const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);const geometry = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), new THREE.MeshBasicMaterial({color: 0xff0000}));const geometry1 = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), new THREE.MeshBasicMaterial({color: 0xff0000}));const geometry2 = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 16), new THREE.MeshBasicMaterial({color: 0xff0000}));geometry1.position.x = 3;geometry2.position.x = -3;scene.add(geometry, geometry1, geometry2);// 控制器const control = new OrbitControls(camera, renderer.domElement);// 开启阻尼惯性,默认值为0.05control.enableDamping = true;// 表示2D vector(二维向量)的类const mouse = new THREE.Vector2();let geometryArr = [geometry, geometry1, geometry2];const raycaster = new THREE.Raycaster();// 监听鼠标点击事件window.addEventListener("mousedown", (event) => {// 转换为一个位于二维空间中的点,在标准化设备坐标中鼠标的二维坐标 —— X分量与Y分量应当在-1到1之间mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;console.log(mouse.x, mouse.y);// 使用一个新的原点和方向来更新射线raycaster.setFromCamera(mouse, camera);// 每次点击循环设置物体初始颜色,如不设置会导致点击物体后颜色变后不能再变for(const geometry of geometryArr) {geometry.material.color.set(0xff0000);}// 相交的物体变色const itgeometrys = raycaster.intersectObjects(geometryArr);for(const itgeometry of itgeometrys) {itgeometry.object.material.color.set(0xcc33f4);}})// 渲染循环动画function animate() {// 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)requestAnimationFrame(animate);// 更新控制器。如果没在动画里加上,那必须在摄像机的变换发生任何手动改变后调用control.update();renderer.render(scene, camera);};// 执行动画animate();</script>
</body>
</html>

在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。


http://www.mrgr.cn/news/24556.html

相关文章:

  • Vue 2 中的 `$set` 方法详解
  • SOME/IP通信协议在汽车业务具体示例
  • LeetCode - 17 电话号码的字母组合
  • 828华为云征文 | Flexus X实例与Harbor私有镜像仓库的完美结合
  • vscode中前端项目文件格式化备份
  • 老旧电力系统安全隐患增加 该如何预防电气线路老化等因素引发的电气火灾呢?
  • SpringBoot基础 -- 框架介绍
  • 云电脑玩《黑神话:悟空》游戏到底咋样?说说心里话…
  • 从大脑图谱/ROI中提取BOLD信号
  • 【C++ Primer Plus习题】14.5
  • 【最新综述】基于深度学习的超声自动无损检测(下)
  • 使用 modelscope产生的问题和解决方案
  • java 中线程的等待和唤醒
  • 【hot100-java】【接雨水】
  • 使用WordCloud报错‘ImageDraw‘ object has no attribute ‘textbbox‘
  • [leetcode-python]最长回文子串
  • Spring Boot 集成 MongoDB - 入门指南
  • 鸿蒙开发(NEXT/API 12)【WebSocket连接】 网络篇
  • 76-mysql的聚集索引和非聚集索引区别
  • 【专题】2024年8月数字化、数智化行业报告合集汇总PDF分享(附原数据表)