threejs项目中,会遇到浏览器宽高变化的情况,这时候我们需要考虑屏幕变化后,画布能够跟随适配。
代码
这里使用的是vue3 获取指定div的宽高来渲染画布。
window.addEventListener('resize', () => {
// 重置相机宽高比
camera.aspect = map3DMain.value.clientWidth / map3DMain.value.clientHeight
// 更新相机矩阵
camera.updateProjectionMatrix();
// 重置渲染器宽高比
renderer.setSize(map3DMain.value.clientWidth, map3DMain.value.clientHeight);
});
实现全屏和退出全屏
点击按钮实现进入全屏以及退出全屏
methods: {
toggleFullscreen() {
if (!document.fullscreenElement) {
this.requestFullscreen(document.documentElement);
} else {
this.exitFullscreen();
}
},
requestFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) { /* Firefox */
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) { /* IE/Edge */
element.msRequestFullscreen();
}
},
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) { /* Firefox */
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { /* IE/Edge */
document.msExitFullscreen();
}
}
},
完整实例代码
<template>
<div class="map3D" ref="Map3D">
<div class="fullscreen" @click="toggleFullscreen">全屏</div>
<div ref="map3DMain" class="map3DMain"></div>
</div>
</template>
<script>
import {onMounted,nextTick, ref} from 'vue';
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
export default {
name: 'map3D',
methods: {
toggleFullscreen() {
if (!document.fullscreenElement) {
this.requestFullscreen(document.documentElement);
} else {
this.exitFullscreen();
}
},
requestFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) { /* Firefox */
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) { /* IE/Edge */
element.msRequestFullscreen();
}
},
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) { /* Firefox */
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) { /* IE/Edge */
document.msExitFullscreen();
}
}
},
setup() {
const map3DMain = ref(null);
onMounted(() => {
/**
* 创建场景对象Scene
*/
var scene = new THREE.Scene();
// 添加世界坐标辅助器
var axesHelper = new THREE.AxesHelper(20);
scene.add(axesHelper);
// 1. 创建几何体: 参数分别是宽、高和深
var geometry = new THREE.BoxGeometry(1, 1, 1);
// 2. 创建材料: 设置为蓝色
var material = new THREE.MeshBasicMaterial({
color: 0x0000ff
});
var parentMaterial = new THREE.MeshBasicMaterial({
color: 0xff0000
});
// 创建子元素
var cube = new THREE.Mesh(geometry, material);
// 创建父元素
var parentCube = new THREE.Mesh(geometry, parentMaterial);
parentCube.add(cube)
parentCube.position.set(-2, 0, 0);
cube.position.set(2, 0, 0);
cube.scale.set(2, 2, 2)
// parentCube.scale.set(2, 2, 2)
// 绕着x轴旋转
cube.rotation.x = Math.PI / 4;
// 父元素旋转
parentCube.rotation.x = Math.PI / 4;
// 4. 添加网格到场景
scene.add(parentCube);
/**
* 光源设置
*/
//点光源
var point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
scene.add(point); //点光源添加到场景中
//环境光
var ambient = new THREE.AmbientLight(0x888888);
scene.add(ambient);
/**
* 透视投影相机设置
*/
var width = map3DMain.value.clientWidth; //窗口宽度
var height = map3DMain.value.clientHeight; //窗口高度
/**透视投影相机对象*/
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
camera.position.set(10, 10, 10); //设置相机位置
// camera.position.set(-40, 40, 830); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
/**
* 创建渲染器对象
*/
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
map3DMain.value.appendChild(renderer.domElement);
//创建控件对象 相机对象camera作为参数 控件可以监听鼠标的变化,改变相机对象的属性
var controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; //开启阻尼效果
// 设置阻尼系数
controls.dampingFactor = 0.05
// 自动旋转
// controls.autoRotate = true; //是否开启自动旋转
function render() {
renderer.render(scene, camera); //执行渲染操作
controls.update();
requestAnimationFrame(render);
}
render();
window.addEventListener('resize', () => {
// 重置相机宽高比
camera.aspect = map3DMain.value.clientWidth / map3DMain.value.clientHeight
// 更新相机矩阵
camera.updateProjectionMatrix();
// 重置渲染器宽高比
renderer.setSize(map3DMain.value.clientWidth, map3DMain.value.clientHeight);
});
});
return {map3DMain};
},
};
</script>
<style lang="scss" scoped>
.map3D {
position: fixed;
width: 100%;
left: 0;
top: 0;
height: 100%;
.map3DMain {
position: relative;
width: 100%;
height: 100%;
}
}
.fullscreen{
position: fixed;
right: 20px;
top: 20px;
cursor: pointer;
padding: 10px 20px;
border-radius: 10px;
color: #fff;
z-index: 10000;
background: #064040;
&:hover {
color: #fff;
}
}
</style>
演示地址
学习笔记
当前内容为 threejs视频教程 Three.js可视化企业实战WEBGL课 -Three.js开发入门与调试设置-响应式画布与全屏控制-学习笔记
笔记代码
笔记代码项目基于vue3 vite js nodejs16 运行
运行效果可查看演示地址:threejs 响应式画布与全屏控制