ThreeJS 之界面控制
文章目录
- 参考
- 描述
- 界面自适应
- 问题
- resize 事件
- 修改画布大小
- 修改视锥体的宽高比
- 全屏显示
- dblclick 事件
- 检测全屏显示状态
- 进入全屏显示状态
- 退出全屏显示状态
- 尾声
参考
| 项目 | 描述 |
|---|---|
| ThreeJS | 官方文档 |
| 哔哩哔哩 | 老陈打码 |
| 搜索引擎 | Bing |
| MDN 文档 | document.mozFullScreenElement |
| MDN 文档 | Element.requestFullscreen() |
| MDN 文档 | Document.exitFullscreen() |
描述
| 项目 | 描述 |
|---|---|
| npm | 8.19.3 |
| node | v16.19.0 |
| Edge | 110.0.1587.41 (正式版本) (64 位) |
| ThreeJS | 0.148.0 |
| webpack | 5.75.0 |
| webpack-cli | 5.0.1 |
注:
在观察本篇博客后续内容前请先搭建 ThreeJS 运行的相关环境,如还未搭建相关环境,请移步至我的另一篇博客 初识 ThreeJS (ThreeJS 相关环境搭建)。
界面自适应
问题
若你未为 ThreeJS 项目设置界面自适应功能,可能会产生如下问题:

在画布创建完成后,改变窗口大小并不会对画布(尺寸)产生影响,于是产生了上图中的空白部分。
resize 事件
当浏览器视口(浏览器的可视区域)发生改变时将触发 Window 对象的 resize 事件。我们可以在该事件对应的事件处理函数中实现界面自适应功能。
// 为 window 对象添加监听器以监听 resize 事件
window.addEventListener('resize', () => {// 在此处实现界面自适应功能
})
修改画布大小
相关
// 导入 ThreeJS
import * as three from 'three';
// 渲染器的创建
const renderer = new three.WebGLRenderer();
主逻辑
window.addEventListener('resize', () => {renderer.setSize(window.innerWidth, window.innerHeight);
})
其中:
- renderer.setSize() 函数用于设置画布的尺寸;该函数接收两个参数,分别用于设置画布的宽度及画布的高度。
- window.innerWidth 与 window.innerHeight 分别对应浏览器视口(浏览器的可视区域)的当前宽度及高度。
执行效果

界面的自适应功能已被实现,但场景中的物体将随浏览器视口尺寸的改变而被拉伸或挤压。
分析:
渲染器以摄像机的各方面属性(位置,角度等)来计算在画布中需要绘制的内容(视锥体)。renderer.setSize() 仅改变了画布大小,并没有改变视锥体的宽高比,所以在我们更改画布大小后场景中的元素将被拉伸。
视锥体
在三维计算机图形学中,视锥体(英语:viewing frustum)又称视景体、视锥,是三维世界中在屏幕上可见的区域,即虚拟摄像机的视野。
该区域的实际形状依所模拟的摄像机镜头而定,但顾名思义,其常见的形状是方平截头体。将四棱锥截为平截头体的两个平面称作近平面 和远平面。如果某个物体到摄像机的距离比近平面近或比远平面远,那么这个物体不会被显示。

上述内容引用自 维基百科
修改视锥体的宽高比
你需要使用摄像机对象的 aspect 属性指定视锥体的宽高比,并使用摄像机对象的 updateProjectionMatrix() 使宽高比生效。
相关
// 导入 ThreeJS
import * as three from 'three';
// 创建透视摄像机
const camera = new three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
透视摄像机
在 ThreeJS 中,你可以使用如下代码创建透视摄像机:
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number );
其中:
| 项目 | 描述 |
|---|---|
| fov | 视锥体垂直视野角度,默认值为 50。 |
| aspect | 视锥体的宽高比,默认值为 1。 |
| near | 规定视锥体近端面与摄像机之间的距离,默认值为 0.1。 |
| far | 规定视锥体远端面与摄像机之间的距离,默认值为 2000。 |
主逻辑
window.addEventListener('resize', () => {renderer.setSize(window.innerWidth, window.innerHeight);// 设置视锥体的宽高比camera.aspect = window.innerWidth / window.innerHeight;// 使得视锥体的宽高比生效camera.updateProjectionMatrix();
})
执行效果

全屏显示
在 Edge 浏览器中,你可以通过敲击 F11 来使得当前页面进入或退出全屏显示。当然你也可以通过 JavaScript 实现用户可以通过其他方式来进入或退出全屏显示。这里我们将实现双击页面进入或退出全屏显示的效果。
dblclick 事件
当你在页面中进行双击操作时将触发 dbclick 事件,我们可以在该事件对应的事件处理函数中实现双击以进入或退出全屏显示的功能。
// 为 window 对象添加监听器以监听 dblclick 事件
window.addEventListener('dblclick', () => {// 在此处实现双击以进入或退出全屏显示的功能
})
检测全屏显示状态
在通过 JavaScript 代码进入或退出全屏显示前,我们需要检测当前的全屏显示状态。你可以通过 document.fullscreenElement 来达成此目的。
document.fullscreenElement
document.fullscreenElement 返回当前文档中正在以全屏模式显示的Element 节点,如果没有使用全屏模式,则返回 null 。
实现
window.addEventListener('dblclick', () => {if(document.fullscreenElement){// 若已有元素进入全屏显示状态,则执行// 此部分代码。}else{// 若无元素进入全屏显示状态将执行// 此部分代码。}
})
注:
通过敲击 F11 进入全屏显示后,document.fullscreenElement 将返回 null 。也就是说,document.fullscreenElement 不能检测到通过敲击 F11 进入全屏显示后的状态。
进入全屏显示状态
Element.requestFullscreen() 方法用于发出异步请求使元素进入全屏模式。
调用此 API 并不能保证元素一定能够进入全屏模式。如果元素被允许进入全屏幕模式,返回的 Promise 会 resolve,并且该元素会收到一个fullscreenchange 事件,通知它已经进入全屏模式。如果全屏请求被拒绝,返回的 promise 会变成 rejected 并且该元素会收到一个fullscreenerror 事件。如果该元素已经从原来的文档中分离,那么该文档将会收到这些事件。
相关
// ThreeJS 的导入
import * as three from 'three';
// 渲染器的创建
const renderer = new three.WebGLRenderer();
进入全屏显示状态
window.addEventListener('dblclick', () => {if(document.fullscreenElement){// 若已有元素进入全屏显示状态,则执行// 此部分代码。}else{renderer.domElement.requestFullscreen();}
})
注:
-
你可以在进入或退出全屏显示状态前对 fullscreenchange 和 fullscreenerror 事件进行监听,以便在某一元素进入或退出全屏显示状态或进行前两种可能(某一元素进入或退出全屏显示状态)时发生错误时进行合适的处理,提高对程序的掌控能力。
-
系统将维护全屏显示栈,若你在进入全屏显示状态后 N 次执行进入全屏显示状态的相关代码,那么你需要执行退出全屏显示状态的操作 N+1 次才能够完全退出全屏显示状态。
退出全屏显示状态
你可以通过执行 document.exitFullScreen() 函数来退出当前所处的全屏显示状态。
window.addEventListener('dblclick', () => {if(document.fullscreenElement){document.exitFullscreen();}else{renderer.domElement.requestFullscreen();}
})
尾声
💕欢迎建议💕 如果你对这篇博客右什么意见,欢迎指出。
💞欢迎提问💞 如果各位对文章中的某些内容不太理解,欢迎提问。
相关文章:
ThreeJS 之界面控制
文章目录参考描述界面自适应问题resize 事件修改画布大小修改视锥体的宽高比全屏显示dblclick 事件检测全屏显示状态进入全屏显示状态退出全屏显示状态尾声参考 项目描述ThreeJS官方文档哔哩哔哩老陈打码搜索引擎BingMDN 文档document.mozFullScreenElementMDN 文档Element.re…...
【查找算法】解析学习四大常用的计算机查找算法 | C++
第二十二章 四大查找算法 目录 第二十二章 四大查找算法 ●前言 ●查找算法 ●一、顺序查找法 1.什么是顺序查找法? 2.案例实现 ●二、二分查找法 1.什么是二分查找法? 2.案例实现 ●三、插值查找法 1.什么是插值查找法? 2…...
Android实例仿真之一
目录 零 开局三问 第一问:为什么要有这一章? 第二问:Android算不算是一个嵌入式系统? 第三问:用什么方法来分析Android这个大系统? 一 讨论Android的流行 二 深入浅出Android 零 开局三问 在正式开始…...
软考高级-信息系统管理师之重要工具和技术的口语化表示(最新版)
重要工具和技术的口语化表示 本文主要介绍重要工具和技术的口语化解释 1、 模板、表格和标准:就是用之前的项目的模版、表格、标准,结合本项目进行了修改,在编制一些计划、方案的时候就可以采用这个工具和技术。可以拿来就用的,节约时间、提高质量的。 2、 产品分析:通过一…...
基于springboot+vue的个人健康信息服务平台
基于springbootvue的个人健康信息服务平台 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背…...
SpringBoot2.x实战专题——SpringBoot2 多配置文件【开发环境、测试环境、生产环境】
SpringBoot2.x实战专题——SpringBoot2 多配置文件【开发环境、测试环境、生产环境】 目录SpringBoot2.x实战专题——SpringBoot2 多配置文件【开发环境、测试环境、生产环境】一、创建一个SpringBoot项目二、修改pom.xml中SpringBoot的版本三、配置文件3.1 application-dev.ym…...
测试2:编写测试用例的方法
2.编写测试用例的方法 7种 测试常用的方法:code review 代码静态分析、CI/CD CI–持续集成–开发成员经常集成它们的工作,尽快发现集成错误 CD–持续部署–将集成后的代码部署到更贴近真实运行的环境 2.1 测试用例的描述: 用例编号 用例…...
docker安装配置镜像加速器-拉取创建Mysql容器示例
List item docker 常见命令大全docker安装docker拉取创建Mysql容器docker 安装 1、安装链接:https://blog.csdn.net/BThinker/article/details/123358697 ; 2、安装完成需要配置docker镜像加速器 3、docker 镜像加速器推荐使用阿里云的: 编…...
WSL1和WSL2相互转换以及安装路径迁移相关问题
目录 1.从WSL 1如何切换到WSL 2? 2.从WSL 2如何切换回WSL 1? 3.WSL1转换为WSL2后,WSL1里面安装的程序和库需要重装吗? 4.WSL2转换为WSL1后,WSL2里面安装的程序和库需要重装吗? 5.如何备份WSL2…...
系统分析*
文章目录系统分析分析的任务结构化方法OO的方法的任务常用的详细调查方法有哪些?系统分析的建模TFD业务流程图DFDDD数据流图用例模型(重点用例图)用例图的内容:用例之间的关系:对象模型(类图)时…...
【redis】持久化:RDB和AOF
redis的持久化指将数据写入可靠内存中,如ssd。Redis提供了4种持久化策略 RDB:Redis Database,周期性的将某个时间点的数据集快照持久化AOF:Append Only File,每次redis服务接收到写操作(修改内存的操作),都…...
2023Python接口自动化测试实战教程,附视频实战讲解
这两天一直在找直接用python做接口自动化的方法,在网上也搜了一些博客参考,今天自己动手试了一下。 一、整体结构 上图是项目的目录结构,下面主要介绍下每个目录的作用。 Common:公共方法:主要放置公共的操作的类,比如数据库sql…...
【原创】java+swing+sqlserver药品管理系统设计与实现
之前数据库都是用的mysql,今天我们使用sqlserver在配合swing来开发一个药品管理系统。方便医院工作人员进行药品的管理,基础功能基本都是一些增删改查操作。 功能分析: 药品管理系统主要提供给管理员和员工使用,功能如下&#x…...
软考高级信息系统项目管理师系列之二十七:信息文档管理与配置管理
软考高级信息系统项目管理师系列之二十七:信息文档管理与配置管理 一、信息文档管理与配置管理内容整理二、信息系统文档管理1.信息系统文档概念2.软件文档分类与质量等级三、配置管理1.配置管理2.典型配置项3.配置项4.配置项操作权限5.配置项状态6.配置项版本号7.配置项版本管…...
软考高级-信息系统管理师之项目管理基础(最新版)
项目管理基础 项目管理特点战略管理三个过程IT项目特点项目管理概念项目管理特点软技能PRINCE2的四个要素组织结构职能型组织优缺点职能型组织优点同时,职能型组织也存在着如下缺点:项目型组织优缺点项目型组织优点项目型组织也存在着如下缺点:矩阵型组织优缺点矩阵型组织的优…...
leetcode240+Search a 2D Matrix II+从右上角开始
链接 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {if(matrix.size()0 || matrix[0].size()0) return false;int i0, jmatrix[0].size()-1; //从右上角开始while (i<matrix.size()&&j>0) {int x mat…...
0xL4ugh 2023
这回跟着个队伍跑,不过还是2X以后的成绩,前边太卷了。自己会的部分,有些是别人已经提交了的。记录一下。Cryptocrypto 1给了一些数据,像这样就没有别的了ct [0, 1, 1, 2, 5, 10, 20, 40, 79, 159, 317, 635, 1269, 2538, 5077, 1…...
Mybatis(4)之跟着老杜做一个简单的银行转账会话
这是个MVC项目,我不一定可以完整的实现这个项目,但力求把这个复现出来,尽量的复现细节。 第一步:创建数据库 表 创建表如下: 我们使用 int 是为了方便 然后采用 demcial,精确度较高 添加两个用户 然后…...
VBA提高篇_ 22 事件处理
文章目录1.事件编程2.常用工作簿事件名称与对应处理过程名称示例3. 事件编程的步骤4.工作簿事件4.1 Open4.2 BeforeClose4.3 NewSheet5.工作表事件6.变量和过程函数的作用域1.事件编程 写在事件发生地(对应工作簿或工作表) 2.常用工作簿事…...
【蓝桥杯集训·周赛】AcWing 第91场周赛
文章目录第一题 AcWing 4861. 构造数列一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第二题 AcWing 4862. 浇花一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第三题 AcWing 4861. 构造数列一、题目1、原题…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...
2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】
1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...
Spring是如何实现无代理对象的循环依赖
无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见:mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简…...
