Angular 11结合Three.js开发出现getBoundingClientRect is not a function报错求助
问题原因
- 核心错误出在构造
images数组的写法有误:document.querySelectorAll('img')返回的是类数组的NodeList对象,你使用{...}对象展开运算符把它转成了普通对象,再套进数组,最终得到的数组第一个元素是键为数字、值为img元素的对象,而非直接存储DOM元素的数组。 - 后续
map遍历的时候拿到的img变量是普通对象,自然没有DOM元素才有的getBoundingClientRect方法,就会抛出对应报错。
修复方案
第一步:修正images数组构造逻辑
把原来的错误写法替换成把NodeList转成元素数组的写法即可:
ngAfterViewInit() { // 两种写法二选一,都是把NodeList转成DOM元素数组 // 写法1:用Array.from let images = Array.from(document.querySelectorAll('img')); // 写法2:用数组展开运算符 // let images = [...document.querySelectorAll('img')]; this.addImages(images); }
第二步:可选优化(避免图片未加载导致尺寸获取错误)
ngAfterViewInit仅保证Angular的视图DOM渲染完成,不保证页面内的图片资源加载完成,此时获取尺寸可能拿到0或者默认占位尺寸,建议等待所有图片加载完成后再执行尺寸计算逻辑,优化后的代码示例:
async ngAfterViewInit() { const images = Array.from(document.querySelectorAll('img')); // 等待所有图片加载完成 await Promise.all(images.map(img => { if (img.complete) return Promise.resolve(); return new Promise(resolve => img.onload = resolve); })) this.addImages(images); } addImages(images) { this.imageStore = images.map(img => { const bounds = img.getBoundingClientRect(); console.log(bounds); const geometry = new THREE.PlaneBufferGeometry(bounds.width, bounds.height, 1, 1); const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }) const mesh = new THREE.Mesh(geometry, material) this.scene.add(mesh); return { img: img, mesh: mesh, top: bounds.top, left: bounds.left, width: bounds.width, height: bounds.height } }) }
内容的提问来源于stack exchange,提问作者user11272367
相关产品推荐
相关产品推荐

