学习threejs,通过THREE.Raycaster给模型绑定点击事件
👨⚕️ 主页: gis分享者
👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨⚕️ 收录于专栏:threejs gis工程师
文章目录
- 一、🍀前言
- 1.1 ☘️THREE.Raycaster光线投射概念
- 二、🍀通过THREE.Raycaster给模型绑定点击事件
- 1. ☘️实现思路
- 2. ☘️代码样例
一、🍀前言
本文详细介绍如何基于threejs在三维场景中实现通过THREE.Raycaster给模型绑定点击事件,亲测可用。希望能帮助到您。一起学习,加油!加油!
1.1 ☘️THREE.Raycaster光线投射概念
THREE.Raycaster 光线投射,常用于和3D图形之间做一些点击事件和交互操作,也可用于碰撞检测等
创建方法:
Raycaster( origin : Vector3, direction : Vector3, near : Float, far : Float )
origin:光线投射的原点向量。
direction:向射线提供方向的方向向量,应当被标准化。
near:返回的所有结果比near远。near不能为负值,其默认值为0。
far:返回的所有结果都比far近。far不能小于near,其默认值为Infinity(正无穷。)
属性
far:远距离因数(投射远点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 这个值不应当为负,并且应当比near属性大。
near:近距离因数(投射近点)。这个值表明哪些对象可以基于该距离而被raycaster所丢弃。 这个值不应当为负,并且应当比far属性小。
camera : 对依赖于视图的对象进行光线投射时使用的相机。默认为空。
layers:Raycaster 在执行相交测试时使用它来选择性地忽略 3D 对象。
ray:用于进行光线投射的射线。
二、🍀通过THREE.Raycaster给模型绑定点击事件
1. ☘️实现思路
- 1、初始化renderer渲染器
- 2、初始化Scene三维场景
- 3、初始化camera相机,定义相机位置 camera.position.set,定义相机方向lookAt。
- 4、加载模型:添加THREE.AxesHelper坐标辅助工具,添加3000个位置随机的THREE.BoxGeometry立方体,scene场景中加入坐标辅助工具和立方体。
- 5、创建THREE.Raycaste光线投射对象,创建onMouseClick事件,定义THREE.Raycaster光线投射与scene中立方体交互事件。
- 6、加入controls,加入stats监控器,监控帧数信息。
2. ☘️代码样例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>learn27(通过THREE.Raycaster给模型绑定点击事件)</title><script src="lib/threejs/127/three.js-master/build/three.js"></script><script src="lib/threejs/127/three.js-master/examples/js/utils/SceneUtils.js"></script><script src="lib/threejs/127/three.js-master/examples/js/controls/OrbitControls.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
</head>
<style>body {margin: 0;}canvas {width: 100%;height: 100%;display: block;}
</style>
<body onload="draw()">
</body>
<script>var renderervar initRender = () => {renderer = new THREE.WebGLRenderer({antialias: true})renderer.setClearColor(0xffffff)renderer.setSize(window.innerWidth, window.innerHeight)document.body.appendChild(renderer.domElement)}var scenevar initScene = () => {scene = new THREE.Scene()}var cameravar initCamera = () => {camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)camera.position.set(0, 40, 100)camera.lookAt(new THREE.Vector3(0, 0, 0))}var initModel = () => {var helper = new THREE.AxesHelper(20)scene.add(helper)var s = 25var cube = new THREE.BoxGeometry(s, s, s)for (var i = 0; i < 3000; i++) {var material = new THREE.MeshBasicMaterial({color: randomColor()})var mesh = new THREE.Mesh(cube, material)mesh.position.x = 800 * ( 2.0 * Math.random() - 1.0 )mesh.position.y = 800 * ( 2.0 * Math.random() - 1.0 )mesh.position.z = 800 * ( 2.0 * Math.random() - 1.0 )mesh.rotation.x = Math.random() * Math.PImesh.rotation.y = Math.random() * Math.PImesh.rotation.z = Math.random() * Math.PImesh.updateMatrix()scene.add(mesh)}}var randomColor = () => {var arrHex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],strHex = "#",index;for (var i = 0; i < 6; i++) {index = Math.round(Math.random() * 15)strHex += arrHex[index]}return strHex}var raycaster = new THREE.Raycaster()var mouse = new THREE.Vector2()var onMouseClick = (event) => {mouse.x = (event.clientX / window.innerWidth) * 2 - 1mouse.y = -(event.clientY / window.innerHeight) *2 + 1raycaster.setFromCamera(mouse, camera)var intersects = raycaster.intersectObjects(scene.children)console.log(intersects)for (var i = 0; i < intersects.length; i++) {intersects[i].object.material.color.set(0xff0000)}}window.addEventListener('click', onMouseClick, false)var statsvar initStats = () => {stats = new Stats()document.body.appendChild(stats.dom)}var controlsvar initControls = () => {controls = new THREE.OrbitControls(camera, renderer.domElement)controls.enableDamping = true}var render = () => {renderer.render(scene, camera)}var onWindowResize = (event) => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()render()renderer.setSize(window.innerWidth, window.innerHeight)}var animate = () => {render()stats.update()controls.update()requestAnimationFrame(animate)}var draw = () => {initRender()initScene()initCamera()initModel()initStats()initControls()animate()window.onresize = onWindowResize}
</script>
</html>
效果如下:

相关文章:
学习threejs,通过THREE.Raycaster给模型绑定点击事件
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.Raycaster光线投射概…...
Jackson Json序列化反序列化的两个坑
Jackson is a suite of data-processing tools for Java (and the JVM platform) Jackson最常用的Json序列化功能,引入如下的包即可: <properties>...<!-- Use the latest version whenever possible. --><jackson.version>2.17.1<…...
k8s_Pod健康检查
Kubernetes 3种探针介绍 LivenessProbe(存活探针) LivenessProbe 用于检查容器是否仍然活着。如果探针检测到容器已经失去响应,Kubernetes 将重启该容器。这通常用来修复由于内部状态错误或死锁引起的程序失效问题。 作用:检测容器…...
基于DDPG算法的股票量化交易
项目源码获取方式见文章末尾! 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【基于PyQTFaceNet卷积神经网络实现的学生人脸识别考勤系统】 2.【卫星图像道…...
eIQ笔记(UI介绍+Loss曲线+OpenART例程)
This is a very beginner-friendly article ^o^ 目录 🍂一、训练器设置 input size: learning rate: learning rate decay: Epochs: Decay Rate: Linear Decay: Batch Size: Epochs to Train: QAT(Quantization Aware Training)量化感知训练: Pruning剪枝…...
微信小程序——消息订阅
首先用到的就是wx.requestSubscribeMessage接口。 注意:用户发生点击行为或者发起支付回调后,才可以调起订阅消息界面 requestSubscribeMessage() {uni.requestSubscribeMessage({tmplIds: [],//需要订阅的消息模板的id的集合,一次调用最多可…...
网络原理(传输层)->TCP协议解
前言 大家好!我是小帅,今天我们来学习TCP协议,个人主页 文章目录 1. TCP协议2. TCP的核心机制2.1TCP核心机制一:确认应答2.2 TCP核心机制二:超时重传2.3 TCP核心机制三:连接管理2.4 TCP核心机制四…...
oracle imp和exp 导入不同库的用户和表空间
参考: oracle 导入(imp)数据时的表空间(tablespace users)问题_imp tablespace-CSDN博客 网上的解决办法大概都是这种,但是实际测试19c数据库并不能成功,所以最后采取在导出文件上强行修改表空间的办法,改完后再继续执行导出导入…...
滚珠丝杆的精度级别如何分?
滚珠丝杆是一种常见的线性传动装置,广泛应用于各种机械设备和自动化系统中。滚珠丝杆的精度等级划分是评估其传动精度和运动平稳度的重要标准,滚珠丝杆的精度级别划分主要基于传动中实际移动距离与理想移动距离的偏差,偏差越小,精…...
ComfyUI初体验
ComfyUI 我就不过多介绍了,安装和基础使用可以看下面大佬的视频,感觉自己靠图文描述的效果不一定好,大家看视频比较方便。 ComfyUI全球爆红,AI绘画进入“工作流时代”?做最好懂的Comfy UI入门教程:Stable D…...
DPI-C动态库so的使用
文章目录 前言一、方法介绍二、demo演示2.1 文件准备2.2 执行仿真2.3 仿真结果 总结 前言 在做IC验证EDA仿真过程中,有时候需要调用C实现的参考模块,我们可以利用DPI-C的功能,实现SV侧调用C侧的函数。 在具体实现过程中,我们可以…...
Java避坑案例 - 高并发场景下的分布式缓存策略
文章目录 概述缓存常见问题及解决方案把 Redis 当作数据库常用的数据淘汰策略如何选择合适的驱逐算法 缓存雪崩问题复现解决方案 缓存击穿(热点缓存失效)问题复现解决方案 缓存穿透问题复现解决方案缓存穿透 vs 缓存击穿 缓存与数据库的一致性先更新缓存…...
Python中的字符串修剪:strip()、lstrip() 和 rstrip()
Python中的字符串修剪 Python 中的字符串修剪:strip()、lstrip() 和 rstrip()strip()lstrip()rstrip()应用场景结论 Python 中的字符串修剪:strip()、lstrip() 和 rstrip() 在 Python 开发中,我们经常需要处理字符串,其中一项常见…...
K8S配置storage-class
简介 Kubernetes支持NFS存储,需要安装nfs-subdir-external-provisioner,它是一个存储资源自动调配器,它可将现有的NFS服务器通过持久卷声明来支持Kubernetes持久卷的动态分配。该组件是对Kubernetes NFS-Client Provisioner的扩展࿰…...
多线程——线程池
目录 前言 一、什么是线程池 1.引入线程池的原因 2.线程池的介绍 二、标准库中的线程池 1.构造方法 2.方法参数 (1)corePoolSize 与 maximumPoolSize (2)keepAliveTime 与 unit (3)workQueue&am…...
VScode插件:前端每日一题
大文件上传如何做断点续传? 在前端实现大文件上传的断点续传,通常会将文件切片并分块上传,记录每块的上传状态,以便在中断或失败时只上传未完成的部分。以下是实现断点续传的主要步骤和思路: 1. 文件切片 (File Slici…...
Android跨进程通信
1、跨进程通信的几种方式 在 Android 中,跨进程通信 (IPC, Inter-Process Communication) 方式有多种,主要用于在不同的应用或进程之间传递数据。常见的跨进程通信方式包括: AIDL (Android Interface Definition Language) • 描述ÿ…...
【初阶数据结构】计数排序 :感受非比较排序的魅力
文章目录 前言1. 什么是计数排序?2. 计数排序的算法思路2.1 绝对位置和相对位置2.2 根据计数数组的信息来确认 3. 计数排序的代码4. 算法分析5. 计数排序的优缺点6.计数排序的应用场景 前言 如果大家仔细思考的话,可能会发现这么一个问题。我们学的七大…...
前后双差速轮之LQR控制
在之前的代码中,我们实现了前后两对双差速轮AGV的运动学正解和逆解。但为了实现对AGV的精确路径跟踪和姿态控制,我们需要引入控制算法。线性二次型调节器(LQR)是一种常用的最优控制方法,可以有效地将系统的状态误差最小化。本文将详细说明如何在之前的C++代码中加入LQR控制…...
Linux之远程连接服务器
1、远程连接服务器简介 (1)什么是远程连接服务器 远程连接服务器通过文字或图形接口方式来远程登录系统,让你在远程终端前登录linux主机以取得可操作主机接口(shell),而登录后的操作感觉就像是坐在系统前面…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
