three.js-实现画布的响应式,根据屏幕尺寸自适应

gitee 地址

gitee地址: gittee地址

本篇目标

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

实现画布的响应式

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

// 设置大小
renderer.setSize(
    window.innerWidth, // 宽度
    window.innerHeight // 高度
);

添加窗口变化监听器

// 添加窗口变化监听器
addEventListener('resize', () => {
    
    
    
})

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

  	// 更新修改相机比例
    camera.aspect = window.innerWidth / window.innerHeight
    // 更新摄像机的投影矩阵
    camera.updateProjectionMatrix()
    // 更新画布大小
    renderer.setSize(
        window.innerWidth, // 宽度
        window.innerHeight // 高度
    );
    // 更新画布像素比
    renderer.setPixelRatio(window.devicePixelRatio)

添加完后的代码

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

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

设置画布全屏和退出全屏

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

// 监听鼠标双击事件
addEventListener('dblclick', () => {
    
    
    // 获取当前状态
    const fullscreenElement = document.fullscreenElement
    if(fullscreenElement){
    
    
        // 退出全屏
        document.exitFullscreen()
        
        return
    }
    // 请求画布全屏
    renderer.domElement.requestFullscreen()
})

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

完整代码

// 引入 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,地址在文章开篇处。

猜你喜欢

转载自blog.csdn.net/qq_44500360/article/details/128202205