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

Vue.js网站中Three.js模型加载缩放异常,切换页面/刷新可临时修复

Vue.js网站中Three.js模型加载缩放异常,切换页面/刷新可临时修复

嘿,我之前也碰到过一模一样的问题!这种情况十有八九是页面刚加载时,Three.js的渲染容器还没拿到正确的布局尺寸,导致模型缩放或者相机参数计算出错了。等你切换页面或者更新布局时,容器尺寸稳定下来,Three.js重新适配了尺寸,模型就显示正常了。

给你几个实用的解决思路:

  • 监听容器尺寸变化,实时更新Three.js参数
    在你的Hyperdrive组件里,用ResizeObserver监听渲染容器的尺寸变化,一旦尺寸改变,就更新相机的宽高比、渲染器尺寸,必要时调整模型缩放。示例代码大概是这样:

    // 假设用Vue 3的Composition API
    import { ref, onMounted, onUnmounted } from 'vue'
    import * as THREE from 'three'
    
    export default {
      setup() {
        const container = ref(null)
        let resizeObserver = null
        let camera = null
        let renderer = null
        let model = null
    
        const initThreeJs = () => {
          // 初始化Three.js核心元素
          const scene = new THREE.Scene()
          camera = new THREE.PerspectiveCamera(75, container.value.clientWidth / container.value.clientHeight, 0.1, 1000)
          renderer = new THREE.WebGLRenderer({ antialias: true })
          renderer.setSize(container.value.clientWidth, container.value.clientHeight)
          container.value.appendChild(renderer.domElement)
    
          // 这里写加载模型的逻辑,示例:
          // const loader = new THREE.GLTFLoader()
          // loader.load('your-model.glb', (gltf) => {
          //   model = gltf.scene
          //   scene.add(model)
          // })
    
          // 渲染循环
          const animate = () => {
            requestAnimationFrame(animate)
            renderer.render(scene, camera)
          }
          animate()
        }
    
        onMounted(() => {
          initThreeJs()
          // 监听容器尺寸变化
          resizeObserver = new ResizeObserver(() => {
            if (camera && renderer && container.value) {
              camera.aspect = container.value.clientWidth / container.value.clientHeight
              camera.updateProjectionMatrix()
              renderer.setSize(container.value.clientWidth, container.value.clientHeight)
              // 如果模型缩放依赖容器尺寸,这里可以动态调整
              // if (model) model.scale.set(container.value.clientWidth / 800, container.value.clientWidth / 800, 1)
            }
          })
          resizeObserver.observe(container.value)
        })
    
        onUnmounted(() => {
          // 销毁监听避免内存泄漏
          if (resizeObserver) resizeObserver.disconnect()
        })
    
        return { container }
      }
    }
    

    记得在Hyperdrive的模板里给容器绑定ref:

    <template>
      <div ref="container" class="hyperdrive-container">
        <!-- Three.js的canvas会自动插入这里 -->
      </div>
    </template>
    
  • 延迟Three.js初始化,等布局稳定后再启动
    有时候页面加载时,容器的CSS布局还没计算完成,你可以用nextTick延迟初始化Three.js,确保容器尺寸已经确定:

    onMounted(async () => {
      // 等待DOM布局更新完成
      await nextTick()
      initThreeJs()
    })
    
  • 检查模型缩放的依赖逻辑
    看看你设置模型scale的代码,是不是用到了容器的初始尺寸(比如刚加载时容器宽度是0或者默认值),如果是这样,要改成获取容器渲染后的实际尺寸,或者用上面的ResizeObserver动态调整。

先试试第一个方法,这个是解决这类布局适配问题最常用的方案,应该能解决你的问题。如果还有疑问,可以再检查下模型加载的时机和容器的CSS样式(比如有没有设置固定宽高,或者用flex/grid布局导致初始尺寸不确定)。

备注:内容来源于stack exchange,提问作者Sloth404

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 08:14:40