如何将数据库数据绑定到Three.js交互对象?数据赋值异常排查
问题分析与解决方案
嘿,我一眼就揪出你遇到undefined问题的根源了——你在循环里错误地访问了整个data数组的属性,而不是数组里的单个元素!
看这段出问题的代码:
cube.userData = { id: data.id, URL: `/vr/${data.id}/`, title: data.title, description: data.description };
data是从API返回的数组,它本身并没有id、title这些属性,这些属性是属于数组里的每一项(也就是data[i])的。所以当你直接写data.id时,自然会得到undefined。
修正后的代码
把循环里的data换成data[i]就能解决问题,顺便帮你把var换成更安全的const/let避免变量提升问题:
async function getData() { try { const response = await fetch('/api/indexvr'); const data = await response.json(); for (let i = 0; i < data.length; i++) { const cube = new THREE.Mesh(geometry, material.clone()); // 这里改成data[i]访问单个元素的属性 cube.userData = { id: data[i].id, URL: `/vr/${data[i].id}/`, title: data[i].title, description: data[i].description }; cube.position.x = i; scene.add(cube); console.log(cube.userData) } } catch (e) { console.error(e) } }
后续功能实现思路
既然你已经搞定了射线检测的hover变色,扩展hover显示标题和点击跳转就很顺畅了:
1. Hover显示标题
- 先在页面上创建一个隐藏的HTML tooltip元素:
<div id="tooltip" style="position: fixed; display: none; background: #333; color: white; padding: 8px; border-radius: 4px; pointer-events: none;"></div> - 在射线检测的逻辑里,根据检测结果控制tooltip的显示:
// 假设你已经有射线检测的intersects结果 if (intersects.length > 0) { const hoveredCube = intersects[0].object; const tooltip = document.getElementById('tooltip'); tooltip.textContent = hoveredCube.userData.title; tooltip.style.display = 'block'; // 让tooltip跟随鼠标移动 tooltip.style.left = `${event.clientX + 10}px`; tooltip.style.top = `${event.clientY + 10}px`; } else { document.getElementById('tooltip').style.display = 'none'; }
2. 点击跳转URL
- 监听鼠标点击事件,结合射线检测实现跳转:
window.addEventListener('click', () => { const intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { const clickedCube = intersects[0].object; window.location.href = clickedCube.userData.URL; } });
作为Three.js新手,这种数组访问的小失误太常见了,不用纠结,修正后就能正常获取数据啦!
内容的提问来源于stack exchange,提问作者Nancy Collins
相关产品推荐
相关产品推荐

