You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:33:18