Three.js中GLTF模型随窗口resize同步调整尺寸的实现疑问
Three.js GLTF模型随窗口大小自适应缩放的实现方法
实现步骤
- 保存模型全局引用:GLTFLoader是异步加载,必须把加载完成的模型存到全局变量中,这样resize事件才能访问到它。
- 计算模型原始尺寸:用
THREE.Box3获取模型的边界框,得到模型自身的宽高比例,避免缩放时变形。 - 在resize事件中计算缩放比例:对比窗口与模型的宽高比,选择合适的缩放因子,让模型适配窗口且保持比例。
- 初始化缩放:模型加载完成后立即执行一次缩放逻辑,确保初始状态就适配当前窗口。
修改后的完整代码
// 全局声明模型变量,供resize事件调用 let backgroundBox; const loader = new GLTFLoader(); // 加载背景盒GLTF模型 loader.load('../../assets/backgroundBox.gltf', function(gltf) { backgroundBox = gltf.scene; scene.add(backgroundBox); // 模型初始配置 backgroundBox.rotation.z = Math.PI / 2; backgroundBox.rotation.y = Math.PI / 2; backgroundBox.castShadow = true; // 加载完成后立即适配窗口尺寸 resizeModel(); }, function(err) { console.log('模型加载出错:', err); }); // 窗口大小改变事件监听 window.addEventListener('resize', () => { const width = window.innerWidth; const height = window.innerHeight; // 更新相机与渲染器配置 camera.aspect = width / height; camera.updateProjectionMatrix(); renderer.setSize(width, height); // 调整模型尺寸 resizeModel(); }); // 模型尺寸适配核心函数 function resizeModel() { if (!backgroundBox) return; // 模型未加载完成时跳过执行 // 获取模型的边界框和实际尺寸 const modelBox = new THREE.Box3().setFromObject(backgroundBox); const modelSize = modelBox.getSize(new THREE.Vector3()); const modelAspect = modelSize.x / modelSize.y; const windowAspect = window.innerWidth / window.innerHeight; let scaleFactor; // 根据宽高比计算缩放因子,保证模型不拉伸且适配窗口 if (windowAspect > modelAspect) { // 窗口更宽,按模型高度匹配窗口高度 scaleFactor = window.innerHeight / modelSize.y; } else { // 窗口更高,按模型宽度匹配窗口宽度 scaleFactor = window.innerWidth / modelSize.x; } // 应用统一缩放(保持模型原有比例) backgroundBox.scale.setScalar(scaleFactor); // 可选:让模型居中显示(根据你的场景需求调整,不需要可以注释) const modelCenter = modelBox.getCenter(new THREE.Vector3()); backgroundBox.position.sub(modelCenter); }
关键细节说明
Box3.setFromObject:这个方法会计算模型所有子物体的边界,得到最准确的模型整体尺寸,不管模型有没有旋转、平移。- 缩放因子逻辑:通过对比窗口和模型的宽高比,选择以高度或宽度为基准缩放,确保模型不会被拉伸变形,且能完整显示在窗口内。
- 模型居中处理:缩放后模型的位置可能偏移,通过计算边界框中心并调整模型位置,可以让模型始终处于窗口中心(不需要的话可以删掉这部分代码)。
- 异步加载判断:在
resizeModel里先检查模型是否存在,避免模型还没加载完就执行缩放导致的报错。
内容的提问来源于stack exchange,提问作者Se00n00
相关产品推荐
相关产品推荐

