Three.js中点击生成的3D模态框添加文本失败求助
在Three.js的3D模态框中添加文本的解决方案
嘿,我看你已经搞定点击创建/移除3D模态框的逻辑了,但卡在给这个模态框加文本这一步对吧?其实Three.js里没法直接给Mesh塞文本,得用专门的方式来实现,我给你两种常用的解决方案,你可以根据需求选:
方法1:用TextGeometry创建3D文本(带立体效果)
这种方法能做出有厚度的3D文本,但需要提前加载字体文件(你可以从Three.js官方示例的fonts文件夹里拿,比如helvetiker_regular.typeface.json)。
修改你的onClick函数如下:
function onClick(object) { if (uiPlane !== undefined) { scene.remove(uiPlane); // 记得同时移除文本网格,避免内存残留 if (t) { scene.remove(t); t = undefined; } uiPlane = undefined; } else { var geometry = new THREE.PlaneGeometry(6, 2, 1); var material = new THREE.MeshBasicMaterial( { color: new THREE.Color("rgb(242, 242, 242)"), side: THREE.DoubleSide }); uiPlane = new THREE.Mesh(geometry, material); uiPlane.name = 'dialog_' + object.name; // 把模态框放在目标物体上方,避免遮挡 uiPlane.position.copy(object.position); uiPlane.position.y += 2; // --- 添加3D文本部分 --- // 建议提前全局加载字体,不要每次点击都加载,这里为了演示写在函数里 const fontLoader = new THREE.FontLoader(); fontLoader.load('helvetiker_regular.typeface.json', function(font) { const textGeometry = new THREE.TextGeometry('这是你的模态框文本', { font: font, size: 0.5, // 文本大小 height: 0.1, // 文本厚度 curveSegments: 12, bevelEnabled: true, // 边缘倒角 bevelThickness: 0.03, bevelSize: 0.02 }); // 文本用黑色,和浅色模态框形成对比 const textMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 }); t = new THREE.Mesh(textGeometry, textMaterial); // 让文本居中 textGeometry.center(); t.position.copy(uiPlane.position); // 微调位置,让文本在模态框上方一点 t.position.y += 0.2; scene.add(t); }); scene.add(uiPlane); } }
注意:字体文件要放在正确的路径下,最好提前在页面加载时就加载好字体,不要每次点击都发起请求,影响性能。
方法2:用Canvas生成文本纹理(快速实现平面文本)
如果不需要3D立体效果,这种方法更简单,不需要额外字体文件,直接用浏览器支持的字体就能生成文本纹理:
function onClick(object) { if (uiPlane !== undefined) { scene.remove(uiPlane); if (t) { scene.remove(t); t = undefined; } uiPlane = undefined; } else { var geometry = new THREE.PlaneGeometry(6, 2, 1); var material = new THREE.MeshBasicMaterial( { color: new THREE.Color("rgb(242, 242, 242)"), side: THREE.DoubleSide }); uiPlane = new THREE.Mesh(geometry, material); uiPlane.name = 'dialog_' + object.name; uiPlane.position.copy(object.position); uiPlane.position.y += 2; // --- 用Canvas创建平面文本 --- const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 画布尺寸和模态框比例一致(100:1) canvas.width = 600; canvas.height = 200; // 画布背景设为透明或者和模态框同色 ctx.fillStyle = '#f2f2f2'; ctx.fillRect(0, 0, canvas.width, canvas.height); // 设置文本样式 ctx.fillStyle = '#000000'; ctx.font = '48px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; // 绘制文本到画布中心 ctx.fillText('这是你的模态框文本', canvas.width/2, canvas.height/2); // 把画布转成Three.js纹理 const textTexture = new THREE.CanvasTexture(canvas); const textMaterial = new THREE.MeshBasicMaterial({ map: textTexture, side: THREE.DoubleSide, transparent: true }); // 创建文本平面,尺寸和模态框一致 const textGeometry = new THREE.PlaneGeometry(6, 2); t = new THREE.Mesh(textGeometry, textMaterial); t.position.copy(uiPlane.position); // 让文本稍微靠前一点,避免和模态框重叠 t.position.z += 0.1; scene.add(t); scene.add(uiPlane); } }
这种方法的好处是快速上手,不需要额外依赖,适合做简单的平面文本提示。
两种方法都能解决你的问题,选哪种看你要不要3D文本的效果~另外记得移除模态框时一定要把文本网格也一起移除,不然会堆积在场景里占用内存哦。
内容的提问来源于stack exchange,提问作者Lex
相关产品推荐
相关产品推荐

