Threejs之看房案例(下)

news2024/11/15 7:26:00

本文目录

  • 前言
  • 最终效果
  • 1、点精灵
    • 1.1 添加点精灵
    • 1.2 点精灵效果
  • 2、添加事件
    • 2.1 鼠标移动事件
      • 2.1.1 效果
    • 2.2 鼠标点击事件
      • 2.2.1 效果
    • 2.3 切换互通
  • 3. 完整代码

前言

在Threejs之看房案例(上)这篇博客中我们已经完成了大厅的3d观看效果,但是我们会发现如果想去其他房间观看,没有交互,接下来我们将完成交互观看的效果。本篇博客已绑定资源包,资源包一键下载后,yarn dev访问http://localhost:5174/three-3d-kanfang/index.html即能一键跑起项目,可以在此基础上依瓢画葫芦,或者修改图片完成自定义的看房项目。

最终效果

请添加图片描述

1、点精灵

点精灵Threejs之看房案例(上)本篇文章的球形模式代码为基础,在此基础上如果需要交互的话,我们使用到射线进行交互。

1.1 添加点精灵

我们首先得有点精灵图进行标识厨房与大厅,加入代码如下所示:

        // 点精灵
        const spriteTexture = textureLoader.load('../assets/tips/kitchen.png');
        const spriteMaterial = new THREE.SpriteMaterial({map: spriteTexture});
        const sprite = new THREE.Sprite(spriteMaterial);
        sprite.name = 'kitchen'; // 可以通过这个属性,与相交的射线判断进入哪个房间
        sprite.scale.set(15, 6, 1);
        scene.add(sprite);

1.2 点精灵效果

请添加图片描述
可以看到效果那就是点精灵厨房位置没对上,那我们其实可以打开坐标轴来设置点精灵位置,打开坐标轴辅助器:

        // 打开坐标轴辅助器
        const axesHelper = new THREE.AxesHelper( 30 );
        scene.add( axesHelper );

效果:
在这里插入图片描述
在这里插入图片描述
我们可看到点精灵x y z轴都要设置为负的:sprite.position.set(-70,0,-50);后效果如下:
请添加图片描述
已经贴在了我们厨房门上。


2、添加事件

2.1 鼠标移动事件

添加鼠标移动事件,我们需要做的是将鼠标移动的点坐标转换为一个位于二维空间中的点,在标准化设备坐标中鼠标的二维坐标 —— X分量与Y分量应当在-1到1之间。然后将这个二维空间中的点方向来更新射线。并且还要将将此向量(坐标)从世界空间投影到相机的标准化设备坐标 (NDC) 空间。代码如下:

        // 事件
        const oHover = document.querySelector('.hover');
        const raycaster = new THREE.Raycaster();
        const mouse = new THREE.Vector2();
        renderer.domElement.addEventListener("mousemove", (event) => {
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
            raycaster.setFromCamera(mouse, camera);
            const intersects = raycaster.intersectObject(sprite);
            
             console.log(intersects);
             if (intersects.length) {
                const worldVector = new THREE.Vector3(
                    intersects[0].object.position.x,
                    intersects[0].object.position.y,
                    intersects[0].object.position.z,
                );
                const dncPosition = worldVector.project(camera); // 将此向量(坐标)从世界空间投影到相机的标准化设备坐标 (NDC) 空间。
                const halfWidth = window.innerWidth/2;
                const halfHeight = window.innerHeight/2;
                const top = -halfHeight*dncPosition.y + halfHeight - 60;
                const left = halfWidth*dncPosition.x + halfWidth;

                oHover.style.top = top + 'px';
                oHover.style.left = left + 'px';
                oHover.style.display = 'block';
             }
             else {
                oHover.style.top = 0 + 'px';
                oHover.style.left = 0 + 'px';
                oHover.style.display = 'none';
             }
        })

2.1.1 效果

效果如下:
请添加图片描述

2.2 鼠标点击事件

好的,我们将进行鼠标点击时进入的厨房的效果。
加入代码:

        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);
            const intersects = raycaster.intersectObject(sprite);

            if (intersects.length && intersects[0].object.name == 'kitchen') {
                const kitchenTexture = textureLoader.load('../assets/kitchen.png');
                const kitchenMaterial = new THREE.MeshBasicMaterial({map: kitchenTexture});
                sphere.material = kitchenMaterial; // 更改贴图为厨房贴图
            }
        })

2.2.1 效果

效果如下:

请添加图片描述
可以看到我们切换到了厨房里,但是会发现我们切换不回去了,并且点精灵位置和描述都不对,接下来我们将实现这一步。

2.3 切换互通

也是在鼠标点击下去的时候判断是不是跳转到客厅,代码如下:

 else if (intersects.length && intersects[0].object.name == 'living') {
                const livingTexture = textureLoader.load('../assets/livingRoom.jpg');
                const livingMaterial = new THREE.MeshBasicMaterial({map: livingTexture});
                sphere.material = livingMaterial; // 更改贴图为厨房贴图
                const kitchenSprite = textureLoader.load("../assets/tips/kitchen.png"); // 加载大厅精灵图 
                const kitchenSpriteMaterial = new THREE.SpriteMaterial({map: kitchenSprite}); // 精灵图
                sprite.name = 'kitchen'; // 厨房
                sprite.material = kitchenSpriteMaterial; // 更改精灵图
                sprite.position.set(-70,0,-50); // 更改位置
            }

效果:
请添加图片描述


3. 完整代码

最后给出完整代码:

<!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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2144643.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3+ant design vue 中弹窗自定义按钮设置及以冒号为基准布局

1、自定义弹窗按钮&#xff0c;去除取消和确定按钮。&#xff08;网上很多方法都是说通过插槽来实现&#xff0c;但是试了下不生效&#xff0c;那既然插槽不生效的话&#xff0c;干脆直接写按钮就好了&#xff09; <a-modalv-model:open"open"title"人员信息…

为什么现在都流行开放式耳机?四款性能出色的蓝牙耳机推荐

在当下&#xff0c;开放式耳机逐渐成为众多消费者的新宠。与传统入耳式耳机相比&#xff0c;开放式耳机展现出诸多独特之处。它可以呈现出更清晰的音质效果&#xff0c;让用户有更美妙的听觉体验。在佩戴感上&#xff0c;开放式耳机更为舒适&#xff0c;不会给耳朵带来压迫感。…

MYSQL登录失败,确保密码正确,常见问题

今天登录MYSQL时&#xff0c;发现登录不进去,我能确保密码没有错误&#xff0c;并且我昨天以这样的方式登录成功&#xff0c;我已经重启过mysql服务&#xff0c;但是依旧登录不进去。 C:\Users\user>mysql -u root -p Enter password: ****** ERROR 1045 (28000): Access …

tidb 集群搭建

官网的搭建文档&#xff1a;使用 TiUP 部署 TiDB 集群 | TiDB 文档中心 我本地使用三台 centos7.9 服务器搭建&#xff0c;要保证三台服务器之间是可以互相通信的&#xff1b; 搭建集群的命令在其中一台服务器上执行即可&#xff1b; 1、安装tiup&#xff1a; curl --proto …

[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离

今天带来一款优秀的项目&#xff1a;个人博客系统源码 。 系统采用的流行的前后端分离结构&#xff0c;内含功能包括 "写博客文章"&#xff0c;“修改博客文章”&#xff0c;“富文本编辑器”&#xff0c;“评论管理”“管理员角色”&#xff0c;“游客角色”&#x…

9.18每日作业

使用cout实现输出斐波那契前20项的值 #include <iostream>using namespace std;int main() {int a 1,b 1;int sum;int i;for(i 0;i<20;i){cout << b << endl;sum ab;b a;a sum;}return 0; }使用cin和cout完成&#xff0c;提示并输入一个字符&#…

canvas画笑脸

用到 stroke()控制线条fill()填充区域&#xff1b;fillStyle填充样式beginPath()和closePath() &#xff1a;两个不相关路径间需要配合使用线性渐变createLinearGradient(x0, y0, x1, y1)&#xff0c; x0:起点的 x 轴坐标。y0&#xff1a;起点的 y 轴坐标。x1&#xff1a;终点…

Mercari煤炉上架产品需要注意什么?Mercari煤炉批量上传工具

Mercari煤炉是日本最大的二手交易平台之一&#xff0c;不仅拥有稳定的日本市场&#xff0c;还扩展到了美国&#xff0c;如今Mercari美国市场用户数量众多&#xff0c;商品从上架到出单的速度很快&#xff0c;通常不会超过三天&#xff0c;上架当然出单的卖家都很多&#xff01;…

硬件基础知识

驱动开发分为&#xff1a;裸机驱动、linux驱动 嵌入式&#xff1a;以计算机技术为基础&#xff0c;软硬结合的、可移植、可剪裁的专用计算机 单片机最小单元&#xff1a;vcc gnd reset 晶振 cpu --- soc :system on chip 片上外设 所有的程序都是在soc&#xff08;cpu&…

[C++进阶[六]]list的相关接口模拟实现

1.前言 本章重点 在list模拟实现的过程中&#xff0c;主要是感受list的迭代器的相关实现&#xff0c;这是本节的重点和难点。 2.list接口的大致框架 list是一个双向循环链表&#xff0c;所以在实现list之前&#xff0c;要先构建一个节点类 template <class T> struct L…

Packet Tracer - 配置编号的标准 IPv4 ACL(两篇)

Packet Tracer - 配置编号的标准 IPv4 ACL(第一篇) 目标 第 1 部分&#xff1a;计划 ACL 实施 第 2 部分&#xff1a;配置、应用和验证标准 ACL 背景/场景 标准访问控制列表 (ACL) 为路由器 配置脚本&#xff0c;基于源地址控制路由器 是允许还是拒绝数据包。本练习的主要内…

华为OD机试 - 最大子矩阵 - 卡德恩算法(动态规划)(Java 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

wav怎么转mp3格式?给你推荐几种音频格式转换方法

wav怎么转mp3格式&#xff1f;将wav文件转换为MP3格式是一个常见的操作&#xff0c;尤其适用于需要节省存储空间或确保文件兼容性的场景。wav文件保存了音频的所有原始数据&#xff0c;这使得它们的文件体积往往非常庞大。相比之下&#xff0c;MP3格式通过有损压缩技术显著减小…

费用管理系统如何优化企业年报台账归集流程?

随着企业规模的扩大和业务的复杂化&#xff0c;财务管理工作的重要性日益凸显。其中&#xff0c;年报台账归集作为财务管理的重要环节&#xff0c;不仅关乎企业财务数据的准确性和完整性&#xff0c;更直接影响到企业决策的科学性和合理性。面对海量的财务数据和复杂的归集要求…

算法训练——day15数组交集(是否去重)

349. 两个数组的交集 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 输出&#xff1a;[2]示例 2&#xff1a; 输入…

AI逻辑推理入门

参考数据鲸 (linklearner.com) 1. 跑通baseline 报名 申领大模型API 模型服务灵积-API-KEY管理 (aliyun.com) 跑通代码 在anaconda新建名为“LLM”的环境,并安装好相应包后,在jupyter notebook上运行baseline01.ipynb 2. 赛题解读 一般情况下,拿到一个赛题之后,我们需…

Python酷库之旅-第三方库Pandas(121)

目录 一、用法精讲 536、pandas.DataFrame.set_axis方法 536-1、语法 536-2、参数 536-3、功能 536-4、返回值 536-5、说明 536-6、用法 536-6-1、数据准备 536-6-2、代码示例 536-6-3、结果输出 537、pandas.DataFrame.set_index方法 537-1、语法 537-2、参数 …

Games101图形学笔记——着色

Shading Z-buffering&#xff08;深度缓冲&#xff09; Shading&#xff08;着色&#xff09;画家算法Z-BufferShading(着色&#xff09;Blinn-Phong Reflectance Model&#xff08;布林冯反射模型&#xff09;漫反射能量守恒 着色高光Blinn-Phong Reflection ModelShadingFreq…

Cpp输出多字符常量警告

Cpp输出多字符常量警告 Cpp中用单引号(single quotes)表示单个字符(single character)&#xff0c;例如a&#xff0c;$&#xff0c;用双引号(double quotes)表示字符串文本(text)&#xff0c;例如"Hello World! " 当在一个单引号里面存在多个字符时&#xff0c;Cpp…

怎么增加音频的音量?这几种方法可以轻松增加音频的音量!

怎么增加音频的音量&#xff1f;在日常生活的纷繁场景中&#xff0c;音频音量偏低的问题往往悄然成为我们不可忽视的困扰&#xff0c;它虽非重大难题&#xff0c;却能在关键时刻带来诸多不便与挑战&#xff0c;设想一下&#xff0c;在喧嚣的街头或拥挤的咖啡馆里&#xff0c;微…