three.js-Responsive canvas, adaptive according to screen size

gitee address

giteeAddress: gittee address

The goal of this article

  • Realize the responsiveness of the canvas, adapting to the screen size
  • Set canvas full screen, and exit full screen

Responsive canvas

We need to use native ones here addEventListenerto monitor changes in our windows.
We need to change the original hard-coded canvas size to the window size

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

Add window change listener

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

After the listener is added, we need to reset its size and ratio in the callback function

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

Added code

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

In this way, no matter how we modify the window, the canvas and camera projection content are in the middle of the screen.

Set canvas full screen and exit full screen

Here to set the request canvas full screen we still need to use the native time addEventListeneras the monitor requestFullscreento request the full screen and exitFullscreenexit the full screen operation.
Go directly to the code:

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

In this way, we have completed the function of setting and exiting the full screen of the canvas.

full code

// 引入 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()

advance notice

Combining dat.guito achieve interface visualization modification and debugging

All operation implementation cases are uploaded to gitee, and the address is at the beginning of the article.

Guess you like

Origin blog.csdn.net/qq_44500360/article/details/128202205