初始化THREE.WebGLRenderer遇domElement只读错误及模型加载暂停咨询
问题解答:THREE.WebGLRenderer初始化错误与模型加载异步处理
一、TypeError: "domElement" is read-only 错误修复
错误核心原因:初始化WebGLRenderer时漏掉了new关键字,直接将构造函数当作普通函数调用。此时函数内部的this指向全局对象(严格模式下为undefined),尝试给this.domElement赋值会触发只读属性的错误。
修复后的Renderer初始化代码:
// 必须添加new关键字创建实例 window.renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("shotgun"), antialias: true, alpha: true });
二、不依赖回调,异步等待模型加载完成
可以将GLTFLoader的回调式加载封装为Promise,配合async/await实现同步风格的异步代码,无需将后续逻辑塞进回调函数:
1. 封装模型加载为Promise函数
function loadModel(url) { return new Promise((resolve, reject) => { const loader = new GLTFLoader(); loader.load( url, (gltf) => resolve(gltf), (xhr) => console.log((xhr.loaded / xhr.total) * 100 + "% loaded"), (error) => reject(error) ); }); }
2. 在async函数中await加载完成
修改原有load函数,直接等待模型加载完成后再执行后续初始化逻辑:
async function load() { // THREE基础环境初始化 window.scene = new THREE.Scene(); window.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // 等待模型加载完成,无需嵌套回调 try { const gltf = await loadModel("/assets/shotgun/scene.gltf"); const model = gltf.scene; scene.add(model); window.shotgun = model; } catch (error) { console.error(error); } // 后续Renderer、灯光、控制器等逻辑 window.renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("shotgun"), antialias: true, alpha: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); camera.position.set(10, 0, 0); var light = new THREE.PointLight(0xffffff); light.position.set(-5, 10, 10); scene.add(light); window.ctrl = new OrbitControls(camera, renderer.domElement); scene.add(new THREE.PointLightHelper(light), new THREE.GridHelper(200, 50)); }
这样代码会在模型加载完成后才继续执行后续逻辑,完全避免了回调嵌套的问题。
内容的提问来源于stack exchange,提问作者RecReo
相关产品推荐
相关产品推荐

