如何在Three.js中实现鼠标悬停BoxGeometry时文字显隐
实现BoxGeometry鼠标悬停显示/隐藏文字的方案
要实现鼠标悬停立方体时显示文字、移开隐藏的效果,核心是用Three.js的**射线检测(Raycaster)**判断鼠标是否命中物体,再动态切换材质控制文字显示。
具体步骤与代码示例
1. 准备基础资源
先做好立方体、基础无文字材质,以及带文字的纹理材质(初始不启用):
// 基础材质(无文字,初始状态用这个) const basicMaterial = new THREE.MeshBasicMaterial({ color: 0xcccccc }); // 创建带文字的画布纹理 const canvas = document.createElement('canvas'); canvas.width = 256; // 用2的幂次方尺寸避免纹理模糊 canvas.height = 256; const ctx = canvas.getContext('2d'); ctx.fillStyle = '#000'; ctx.font = '48px Arial'; ctx.fillText("Alok", 60, 130); // 注意是fillText,不是filltext(大小写敏感) const textTexture = new THREE.CanvasTexture(canvas); const textMaterial = new THREE.MeshBasicMaterial({ map: textTexture }); // 创建立方体,初始用基础材质 const boxGeo = new THREE.BoxGeometry(2, 2, 2); const boxMesh = new THREE.Mesh(boxGeo, basicMaterial); scene.add(boxMesh);
2. 配置鼠标交互与射线检测
监听鼠标移动,在动画循环里实时检测是否击中立方体,动态切换材质:
const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); // 把浏览器鼠标坐标转成Three.js需要的标准化坐标 window.addEventListener('mousemove', (e) => { mouse.x = (e.clientX / window.innerWidth) * 2 - 1; mouse.y = -(e.clientY / window.innerHeight) * 2 + 1; }); // 动画循环里做交互检测 function animate() { requestAnimationFrame(animate); // 更新射线的检测起点和方向 raycaster.setFromCamera(mouse, camera); // 检测是否击中目标立方体 const hits = raycaster.intersectObject(boxMesh); if (hits.length > 0) { // 鼠标悬停,切换到带文字的材质 boxMesh.material = textMaterial; } else { // 鼠标移开,切回基础材质 boxMesh.material = basicMaterial; } renderer.render(scene, camera); } animate();
3. 可选优化方案
- 不想切换整个材质的话,可以给文字材质加
transparent: true,初始opacity: 0,悬停时设为opacity: 1,这样不用切换材质,只改透明度。 - 如果只想在立方体某一个面显示文字,给BoxGeometry的对应面单独分配材质数组,只修改目标面的材质状态即可。
重要注意点
- 原代码里的
filltext是拼写错误,必须写成fillText(JavaScript方法名大小写敏感),否则文字绘制不出来。 - 画布尺寸尽量用2的幂次方(比如256、512),Three.js对这类尺寸的纹理支持更好,不会模糊。
- 射线检测必须放在动画循环里执行,才能实时响应鼠标位置变化。
内容的提问来源于stack exchange,提问作者Alok Walunj
相关产品推荐
相关产品推荐

