文章目录
- 参考
- 描述
- 界面自适应
- 问题
- 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();
}
})
尾声
💕欢迎建议💕 如果你对这篇博客右什么意见,欢迎指出。
💞欢迎提问💞 如果各位对文章中的某些内容不太理解,欢迎提问。