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
相关产品推荐
相关产品推荐

