gitee 地址

gitee地址: gittee地址

本篇目标

  • 实现画布的响应式,根据屏幕尺寸自适应
  • 设置画布全屏,和退出全屏

实现画布的响应式

我们这里需要用到原生的addEventListener用来监听我们窗口的变化。
我们需要将原来写死的画布大小改成窗口大小

1
2
3
4
5
// 设置大小
renderer.setSize(
window.innerWidth, // 宽度
window.innerHeight // 高度
);

添加窗口变化监听器

1
2
3
4
// 添加窗口变化监听器
addEventListener('resize', () => {

})

监听器添加完成后,我们需要在回调函数里面,重新设置其大小和比例

1
2
3
4
5
6
7
8
9
10
11
// 更新修改相机比例
camera.aspect = window.innerWidth / window.innerHeight
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix()
// 更新画布大小
renderer.setSize(
window.innerWidth, // 宽度
window.innerHeight // 高度
);
// 更新画布像素比
renderer.setPixelRatio(window.devicePixelRatio)

添加完后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 添加窗口变化监听器
addEventListener('resize', () => {
// 更新修改相机比例
camera.aspect = window.innerWidth / window.innerHeight
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix()
// 更新画布大小
renderer.setSize(
window.innerWidth, // 宽度
window.innerHeight // 高度
);
// 更新画布像素比
renderer.setPixelRatio(window.devicePixelRatio)
})

这样无论我们怎么修改窗口,画布和相机投影内容都在屏幕的中间。

设置画布全屏和退出全屏

这里设置请求画布全屏我们依然需要使用原生时间addEventListener作为监听,requestFullscreen来请求全屏,exitFullscreen来退出全屏操作。

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 监听鼠标双击事件
addEventListener('dblclick', () => {
// 获取当前状态
const fullscreenElement = document.fullscreenElement
if(fullscreenElement){
// 退出全屏
document.exitFullscreen()

return
}
// 请求画布全屏
renderer.domElement.requestFullscreen()
})

这样我们设置和退出画布全屏的这个功能就做好了。

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 引入 three.js
import * as THREE from "three"
// 引入控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"

// 目标:实现画布响应式,设置画布全屏、退出全屏

//创建场景
const scene = new THREE.Scene()

// 创建相机
/*
PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面
*/
// 透视相机
const camera = new THREE.PerspectiveCamera(
75, // 摄像机视锥体垂直视野角度,从视图的底部到顶部,以角度来表示。默认值是50。
window.innerWidth / window.innerHeight, // 摄像机视锥体的长宽比,通常是使用画布的宽/画布的高。默认值是1(正方形画布)。
0.1, // 摄像机的近端面,默认值是0.1。
1000 // 摄像机的远端面,默认值 2000
)


// 创建渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿
});
// 设置大小
renderer.setSize(
window.innerWidth, // 宽度
window.innerHeight // 高度
);
//挂载到页面
document.body.appendChild(renderer.domElement)


// 添加控制器
const controls = new OrbitControls( camera, renderer.domElement );
// 开启控制器的阻尼效果
controls.enableDamping = true
// 使用控制器
controls.update()


// 添加物体
/*
width:立方体x轴的长度,
height:立方体y轴的长度,
depth:立方体z轴的长度也是深度
*/
let geometry = new THREE.BoxGeometry(5, 5, 5);

// 添加材质
// const material = new THREE.MeshBasicMaterial({ color: 0xffff0000 });

// 添加材质
const materials = []
for(let i = 0; i < 6; i++){
materials.push(
new THREE.MeshBasicMaterial({
color: Math.random() * 0x00ff0000
})
)
}

// 添加网格
const cube = new THREE.Mesh( geometry, materials );
scene.add( cube );

// 设置相机位置
camera.position.z = 50;

// 修改场景背景颜色
scene.background = new THREE.Color(0xffffcc99)

// 添加 三色坐标轴
const axesHelper = new THREE.AxesHelper(20)
scene.add( axesHelper )

// 添加窗口变化监听器
addEventListener('resize', () => {
// 更新修改相机比例
camera.aspect = window.innerWidth / window.innerHeight
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix()
// 更新画布大小
renderer.setSize(
window.innerWidth, // 宽度
window.innerHeight // 高度
);
// 更新画布像素比
renderer.setPixelRatio(window.devicePixelRatio)
})


// 监听鼠标双击事件
addEventListener('dblclick', () => {
// 获取当前状态
const fullscreenElement = document.fullscreenElement
if(fullscreenElement){
// 退出全屏
document.exitFullscreen()

return
}
// 请求画布全屏
renderer.domElement.requestFullscreen()
})


// 渲染
function animate() {

// 使用 requestAnimationFrame 执行动画
requestAnimationFrame(animate)

controls.update()

//scene:前面定义的场景,camera:前面定义的相机
//renderTarget:渲染的目标默认是是渲染到前面定义的render变量中
//forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除
renderer.render(scene, camera)
}

// 渲染
animate()

下期预告

结合dat.gui实现界面可视化修改及调试

所有操作实现案例均以上传gitee,地址在文章开篇处。