ThreeJS :给立方体各面加上文字
ThreeJS 对文本的处理相对薄弱,它提供有一个扩展几何体 TextGeometry,需要加载字体,且对非英文字体一点都不友好。故此,若需要给立方体每一个面都添加文本,需要另辟蹊径,其中,通过离线 canvas 绘制文本然后作为纹理贴图贴到立方体的每一个面,是个很常见的实现方法。
ThreeJS 本身就是通过 canvas 标签在2d平面上绘制3d效果,它对 canvas 的支持度非常好,核心库内置有canvas纹理,一个 CanvasTexture 类,构造器复杂无比(CanvasTexture),不过没关系,通常用到的参数主要只是一个 canvas 标签,像这样:
const texture = new THREE.CanvasTexture(canvasElement);
canvasElement 即为canvas画布元素,其上应该是已经绘制好了所需文本。为此,需要熟悉 canvas 绘制文本功能,可以参阅 canvas绘制文本 加以学习掌握,主要学习其上介绍的 fillText 方法,因为 ThreeJS 貌似对 strokeText 支持不好。
为方便复用,我编写了一个在 canvas 画布上绘制文本的函数:
function mkText(txt, font, color, bg, w, h) { const canv = document.createElement('canvas'); canv.width = w; canv.height = h; const ctx = canv.getContext('2d'); ctx.fillStyle = bg; ctx.fillRect(0, 0, w, h); // 绘制矩形(面的背景色) ctx.font = font; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillStyle = color; ctx.fillText(txt, w/2, h/2); // 绘制文本 return canv; };
参数解释:
1. txt : 输出的文本,文本型
2. font : 字体设置,字符型,例如,'bold 20px "宋体"'
3. color : 文本颜色,字符型
4. bg : 背景色,字符型
5. w : 宽度,数值型
6. h : 高度,数值型
可以根据需要修改绘制文本的函数。这是离线创建的 canvas 标签,它没有添加到文档中,不会显示出来。函数返回(return)所创建的 canvas 画布 canv,所以,下一步,以其返回值创建 ThreeJS 纹理:
const texture = new THREE.CanvasTexture( mkText( '文字', // 1. 输出的文本 'bold 24px "微软雅黑"', // 2. 字体设置 'white', // 3. 前景色 'purple', // 4. 背景色 100, // 5. 宽度 50 // 6. 高度 ) ); // 代码可以写在一行 // const texture = mkText('文字', '24px "微软雅黑"', 'white', 'purple', 100, 50)
最后创建立由方体几何体 BoxGeometry 和六个面的基础材质 MeshBasicMaterial 构建而成的 Mesh 网格,再初始化 Mesh 的 Pose,加上旋转动画,就大功告成。下面是完整代码,可在线运行:
<script type="module"> import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js'; basic3(); const texts = ['1', '2', '3', '4', '5', '6']; let faces = []; texts.forEach(text => { const texture = new THREE.CanvasTexture(mkText(text, 'bold 24px "微软雅黑"', 'white', 'purple', 100, 50)); faces.push(new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff, map: texture})); }); const mesh = new THREE.Mesh(new THREE.BoxGeometry(), faces); mesh.rotateY(Math.PI / 4); scene.add(mesh); animate(); function animate() { requestAnimationFrame(animate); const delta = clock.getDelta(); mesh.rotation.x -= delta / 2; renderer.render(scene, camera); }; function mkText(txt, font, color, bg, w, h) { const canv = document.createElement('canvas'); canv.width = w; canv.height = h; const ctx = canv.getContext('2d'); ctx.fillStyle = bg; ctx.fillRect(0, 0, w, h); ctx.font = font; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillStyle = color; ctx.fillText(txt, w/2, h/2); return canv; }; </script>
前一篇: ThreeJS 直管道
下一篇: ThreeJS点材质着色问题
评论列表 [1条]
#1 | 飞飞 于 2025-6-19 11:29 发布: 这样添加上文字跟骰子似的