全屏 · Responsive / Resize · ▶ 在线运行案例
案例合集: 三维可视化功能案例(threehub.cn)
开源仓库github地址: https://github.com/z2586300277/three-cesium-examples
**400个案例代码: ** 网盘链接

你将学到什么
- 窗口尺寸变化时 同步更新 renderer 和 camera
camera.aspect与updateProjectionMatrix()的关系- 为什么 resize 后画面会拉伸/压扁
效果说明
拖动浏览器窗口大小时,canvas 和 3D 画面 保持正确比例,物体不会变形。
核心概念
透视相机的 宽高比 aspect 必须等于 canvas 宽高比:
camera.aspect = width / height;
camera.updateProjectionMatrix(); // 重新计算投影矩阵
renderer.setSize(width, height);
不 updateProjectionMatrix 会怎样?
Three.js 不会每帧自动重算投影矩阵(性能考虑)。aspect 变了但不 update → 画面 被拉伸。
resize 监听
window.onresize = () => {
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight);
camera.aspect = box.clientWidth / box.clientHeight;
camera.updateProjectionMatrix();
renderer.render(scene, camera); // 静态场景需手动重绘
};
若有 rAF 循环,resize 里可以不手动 render(下一帧会自动画)。
实现步骤
- 初始 setSize + render
- 绑定 window.onresize
- resize 内更新 renderer 尺寸 + camera.aspect + updateProjectionMatrix
代码要点
import * as THREE from 'three';
// 场景
const scene = new THREE.Scene();// 创建场景
const geometry = new THREE.BoxGeometry(10, 60, 100); //几何体
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); //材质
const mesh = new THREE.Mesh(geometry, material); //网格模型
mesh.position.set(0, 10, 0); //网格模型位置
scene.add(mesh); //场景添加网格模型
// AxesHelper
const axesHelper = new THREE.AxesHelper(150);
scene.add(axesHelper);
// 相机
const camera = new THREE.PerspectiveCamera(); //相机
camera.position.set(200, 200, 200); //相机位置
camera.lookAt(0, 10, 0); //相机观察位置
// 渲染器
const renderer = new THREE.WebGLRenderer(); // 创建渲染器
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight); //渲染区域
renderer.render(scene, camera); //执行渲染
box.appendChild(renderer.domElement);;
// onresize 事件会在窗口被调整大小时发生
window.onresize = function () {
// 重置渲染器输出画布canvas尺寸
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight);
// 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
// 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
// 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
camera.updateProjectionMatrix();
};
完整源码:GitHub
小结
入门案例 · Three.js · 15/15 · 返回入门目录