Three.js场景随窗口高度缩小问题:如何让场景边缘始终贴合屏幕?
解决Three.js纵向调整画布时场景缩放的问题
要让岩石始终贴合屏幕垂直边缘,核心思路是固定垂直方向的可视范围,仅根据窗口宽高比动态调整水平方向的可视区域,超出水平范围的内容自然裁切(就像你提供的移动端效果),而非缩放整个场景适配画布。以下分两种常用相机类型给出解决方案:
一、使用透视相机(PerspectiveCamera)
透视相机的垂直视场角(fov)决定了垂直方向的可视范围,我们要保持这个值不变,仅更新宽高比:
- 初始化相机
先根据场景内容的垂直高度,计算出刚好填满屏幕的垂直视场角。假设岩石垂直方向总高度为viewHeight,相机到岩石的距离为distance,视场角可通过公式计算:
const viewHeight = 10; // 替换为你场景中岩石的实际垂直高度 const distance = 20; // 替换为相机到岩石的实际距离 const fov = 2 * Math.atan(viewHeight / (2 * distance)) * (180 / Math.PI); const camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, 0.1, 1000);
- 监听窗口 resize 事件
每次窗口尺寸变化时,更新相机宽高比、投影矩阵,同步调整渲染器尺寸:
window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });
二、使用正交相机(OrthographicCamera)
正交相机的top和bottom参数控制垂直可视范围,我们固定这两个值,仅动态计算left和right:
- 初始化相机
先定义垂直方向的范围,再根据初始宽高比计算水平范围:
const top = 5; // 替换为你场景中垂直方向的实际可视范围 const bottom = -top; const aspect = window.innerWidth / window.innerHeight; const left = -top * aspect; const right = top * aspect; const camera = new THREE.OrthographicCamera(left, right, top, bottom, 0.1, 1000);
- 监听窗口 resize 事件
保持垂直范围不变,重新计算水平范围并更新相机:
window.addEventListener('resize', () => { const aspect = window.innerWidth / window.innerHeight; camera.left = -camera.top * aspect; camera.right = camera.top * aspect; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });
额外注意事项
如果使用了OrbitControls等控制器,需要同步更新控制器的宽高比:
window.addEventListener('resize', () => { // ... 上述相机更新代码 controls.aspect = window.innerWidth / window.innerHeight; controls.update(); });
内容的提问来源于stack exchange,提问作者Ashbury
相关产品推荐
相关产品推荐

