Threejs之看房案例(下)

news/2024/9/18 20:40:48 标签: 3d, 数码相机, webgl, threejs, 前端

本文目录

  • 前言
  • 最终效果
  • 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 );

效果:
3d18d231c8dc4.png" alt="在这里插入图片描述">
在这里插入图片描述
我们可看到点精灵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.niftyadmin.cn/n/5664490.html

相关文章

好用的超声波清洗机有哪些?精选四大爆款品牌汇总

随着时代的发展及生活水平的提升&#xff0c;珠宝饰品、眼镜等个人物品日益普及至千家万户。然而&#xff0c;这些贵重小物在日常存放中难免会积累微尘与隐形细菌&#xff0c;无形中可能对我们的健康产生潜在影响。鉴于细菌的微小难察&#xff0c;超声波清洗机应运而生&#xf…

进程监控与管理详解

一、进程的定义: 进程process是正在运行的程序,包括: 分配的内存地址空间 安全属性、包括所有权和特权 一个或多个线程 进程状态 进程的环境包括: 本地和全局变量 当前调度上下文…

【每日一题】LeetCode 815.公交路线(广度优先搜索、数组、哈希表)

【每日一题】LeetCode 815.公交路线&#xff08;广度优先搜索、数组、哈希表&#xff09; 题目描述 给定一个表示公交线路的数组 routes&#xff0c;其中每个 routes[i] 表示第 i 辆公交车的循环行驶路线。现在从 source 车站出发&#xff0c;要前往 target 车站&#xff0c;…

Linux | 进程间通信:管道、消息队列、共享内存与信号量

文章目录 《深入理解进程间通信&#xff1a;管道、消息队列、共享内存与信号量》一、进程间通信介绍&#xff08;一&#xff09;进程间通信目的&#xff08;二&#xff09;进程间通信发展&#xff08;三&#xff09;进程间通信分类 二、管道&#xff08;一&#xff09;什么是管…

C++:字符串string转成整型int

一、atoi atoi 是 C 标准库中的一个函数&#xff0c;全称是 ASCII to Integer&#xff0c;用于将字符串转换为整数。 函数定义 int atoi(const char *str);参数&#xff1a;str 是一个指向以 \0 结尾的字符串的指针。返回值&#xff1a;返回字符串转换后的整数。如果字符串中…

Flutter Android Package调用python

操作步骤 一、创建一个Flutter Package 使用以下指令创建一个Flutter Package flutter create --templateplugin --platformsandroid,ios -a java flutter_package_python 二、修改android/build.gradle文件 在buildscript——>dependencies中添加以下内容 //导入Chaqu…

【2024】前端学习笔记7-颜色-位置-字体设置

学习笔记 1.定义&#xff1a;css2.颜色&#xff1a;color3.字体相关属性&#xff1a;font3.1.字体大小&#xff1a;font-size3.2.字体风格&#xff1a;font - style3.3.字体粗细&#xff1a;font - weight3.4.字体族&#xff1a;font - family 4.位置&#xff1a;text-align 1.…

如何看待IBM中国研发部裁员?

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; IBM中国研发部裁员及撤出背景分析 IBM&#xff08;International Business Machines&#xff09;作为全球科技巨头之一&#xff0c;其在中国市场的发展曾是中国信息技术产业的重要组成部分。近年来&#x…