HTML转Laravel/Vue时Three.js r69顶点length属性读取报错
解决Three.js中
geometry.vertices未定义的报错 问题原因
你遇到的Cannot read properties of undefined (reading 'length')报错,核心是代码尝试访问geometry.vertices但该属性不存在,主要有两个诱因:
- 实际安装的Three.js版本并非预期的r69(对应npm版本0.69.0)——新版本Three.js已彻底移除
Geometry类,改用BufferGeometry,不再提供vertices属性。 - Vue组件中代码执行时机过早,DOM未完全渲染,但该因素一般不会直接导致
geometry.vertices未定义,更多引发渲染类问题。
解决方案
方案一:确保使用Three.js r69版本
检查当前安装版本:
在项目根目录执行命令:npm list three确认输出版本为
0.69.0。版本不符则重装指定版本:
npm uninstall three npm install three@0.69.0调整Vue代码执行时机:
将test.js的逻辑放在组件的mounted钩子中执行,确保DOM元素#scene已存在:<template> <canvas id="scene"></canvas> </template> <script> import * as THREE from "three"; export default { mounted() { // 放入test.js的所有代码 const canvas = document.querySelector("#scene"); const width = canvas.offsetWidth; const height = canvas.offsetHeight; // ... 剩余代码 } } </script>
方案二:适配新版本Three.js(推荐,规避旧版本兼容性问题)
若不想依赖老旧的r69版本,可修改代码适配当前Three.js的BufferGeometry结构:
安装最新版Three.js:
npm install three修改核心代码逻辑:
- 替换顶点遍历逻辑,使用
BufferGeometry的attributes.position - 存储原始顶点数据到自定义属性
- 更新顶点后标记属性需要更新
- 替换顶点遍历逻辑,使用
修改后的关键代码片段:
var geometry = new THREE.IcosahedronGeometry(120, 4); // 存储原始顶点数据(BufferGeometry的position是Float32Array) const positions = geometry.attributes.position.array; geometry.userData.originalPositions = [...positions]; // 拷贝原始坐标 var shape = new THREE.Mesh(geometry, material); scene.add(shape); function updateVertices(a) { const originalPositions = geometry.userData.originalPositions; const positions = geometry.attributes.position.array; // 每3个元素对应一个顶点的x/y/z坐标 for (var i = 0; i < originalPositions.length; i += 3) { let x = originalPositions[i]; let y = originalPositions[i+1]; let z = originalPositions[i+2]; var perlin = noise.simplex3( x * 0.006 + a * 0.0002, y * 0.006 + a * 0.0003, z * 0.006 ); var ratio = perlin * 0.4 * (mouse.y + 0.3) + 0.9; // 更新顶点坐标 positions[i] = x * ratio; positions[i+1] = y * ratio; positions[i+2] = z * ratio; } geometry.attributes.position.needsUpdate = true; // 标记属性需更新 }
注意:代码中用到的noise.simplex3需确保已引入Perlin噪声库;TweenMax需替换为新版GSAP的gsap(新版本GSAP已废弃TweenMax)。
内容的提问来源于stack exchange,提问作者user19367608
相关产品推荐
相关产品推荐

