全屏
Responsive / Resize

你将学到什么
- 窗口尺寸变化时 同步更新 renderer 和 camera
camera.aspect与updateProjectionMatrix()的关系- 为什么 resize 后画面会拉伸/压扁
效果说明
拖动浏览器窗口大小时,canvas 和 3D 画面 保持正确比例,物体不会变形。
核心概念
透视相机的 宽高比 aspect 必须等于 canvas 宽高比:
js
camera.aspect = width / height;
camera.updateProjectionMatrix(); // 重新计算投影矩阵
renderer.setSize(width, height);不 updateProjectionMatrix 会怎样?
Three.js 不会每帧自动重算投影矩阵(性能考虑)。aspect 变了但不 update → 画面 被拉伸。
resize 监听
js
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
代码要点
js
window.onresize = () => {
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight);
camera.aspect = box.clientWidth / box.clientHeight;
camera.updateProjectionMatrix();
};devicePixelRatio
高清屏还需 renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)),resize 时一并更新。详见 threejs-fundamentals 场景搭建。
源码
js
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);
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);
window.onresize = () => {
const box = document.getElementById('box');
renderer.setSize(box.clientWidth, box.clientHeight);
camera.aspect = box.clientWidth / box.clientHeight;
camera.updateProjectionMatrix();
};小结
入门案例 · Three.js · 15/15 · 返回入门目录
