监听窗口大小变化,改变画面大小-[Three.js]-[onResize]


如果没有监听窗口变化,将会出现一下情况:


为了避免这种情况,有时候我们可能希望我们的画面能够随着浏览器窗口大小的变化自适应变化,如下效果:


怎么实现呢?

首先,我们需要像这样注册一个事件监听器

window.addEventListener('resize',onResize,false)

我们给这个监听器设置了一个回调函数,也就是说,现在,只要浏览器窗口大小一改变,onResize这个函数就会被触发,我们接下来定义该回调函数的动作,我们需要在该函数中,实现更新camerarenderer,如下:

function onResize(){
    camera.aspect = window.innerWidth/window.innerHeight;//相机视角长宽比
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth,window.innerHeight);
}

其中updateProjectionMatrix()方法,是相机的一个方法,用以更新相机视角模型。每当浏览器画布窗口大小变化,这个onResize函数就会被触发,它首先通过window对象获取了最新的画布长宽比,并让相机的视角大小等于该比值,然后启用updateProjectionMatrix()方法,更醒相机的视角大小,最后,改变renderer的大小,即渲染器的大小(画布大小)。注意是,修改了相机的aspect视角大小,和画布的大小,我们一般都会保持相机视角和画布的长宽比相等,相机是相机,画布是画布。

相关代码如下:

//文件initialization.js
function init() {
    var stats = initStats();
    var renderer = initRenderer();
    var camera = initCamera();
    var scene = new THREE.Scene();
    var clock = new THREE.Clock();

    initDefaultLighting(scene);
    initModel()
    initControls();
    render();
    draw(scene);

    function initModel() {
        //辅助工具
        var helper = new THREE.AxesHelper(900);
        scene.add(helper);
        // var map = new THREE.TextureLoader().load("./assets/jay.jag");
        //外部盒子
        // var material = new THREE.MeshLambertMaterial({
        //     // map: map
        //     color: 0xffffff,
        // });
        // material.transparent = true;
        // material.opacity = 0.4;

        //--------------------------------地板--------------------------
        var planeGeometry = new THREE.PlaneGeometry(1000, 1000, 50, 50);
        var planeMaterial = new THREE.MeshLambertMaterial({
            color: 0xff00000,
            wireframe: true
        });
        planeMaterial.transparent = true;
        planeMaterial.opacity = 0.3;

        plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.rotation.x = -0.5 * Math.PI;
        plane.position.x = 0;
        plane.position.y = -6;
        plane.position.z = 0;


        //告诉底部平面需要接收阴影
        plane.receiveShadow = true;

        scene.add(plane);
        // scene.add(PlaneSegs);
        //--------------------------------地板end-----------------------
    }

    //初始化控制器
    var obtControls; //定义控制器变量
    function initControls() {
        //定义控制器核心           
        obtControls = new THREE.OrbitControls(camera, renderer.domElement);

        // 如果使用animate方法时,将此函数删除
        // controls.addEventListener('change', render);
        //以下都是为了满足各种需求的各种控制器配置参数
        obtControls.enableDampling = true; //使动画循环使用时阻尼或自转 意思是否有惯性
        obtControls.enableZoom = true; //是否允许缩放
        obtControls.enablePan = true; //是否开启鼠标右键拖拽
        obtControls.autoRotate = false; //是否允许自动旋转
        obtControls.dampingFactor = 0.25; //动态阻尼系数:就是鼠标拖拽旋转灵敏度
        obtControls.minDistance = 200; //设置相机距离原点的最近距离;
        obtControls.maxDistance = 1000; //设置相机距离原点的最远距离;

    }
    //窗口大小变化监听
    window.addEventListener('resize',onResize,false);

    function onResize(){
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth,window.innerHeight)
    }

    //控制更新
    function render() {
        stats.update();
        // fpControls.update(clock.getDelta());
        obtControls.update(clock.getDelta());
        requestAnimationFrame(render);
        renderer.render(scene, camera)
    }

}

该demo的完整代码在这里:Link

相关