Three.js使用THREE.TextGeometry创建三维文本实现教程
程序员文章站
2023-09-20 16:05:45
简介
之前我们通过使用three.extrudegeometry来拉伸二维图形生成三维图形。这次我们通过使用three.textgeometry来实现字体的3d化。
实现
实...
简介
之前我们通过使用three.extrudegeometry来拉伸二维图形生成三维图形。这次我们通过使用three.textgeometry来实现字体的3d化。
实现
实现还是和别的几何体一样通过实例化three.textgeometry来创建
var geometry = new three.textgeometry(text,options);
第一个参数是需要显示的字体 第二个参数是相关的配置项,如下
相关配置项
属性 | 是否必需 | 描述 |
---|---|---|
font | 是 | 新版本的字体是以json格式保存,我们需要通过异步加载进入页面,所以,必需在加载完字体以后才能够实例化。 |
size | 否 | 该属性指定文本的大小。默认值为100 |
height | 否 | 该属性指定拉伸的长度(深度)。默认值为50 |
weight | 否 | 该属性指定字体的粗细。可选值包括normal和bold。默认值为normal。 |
style | 否 | 该属性指定字体的样式。可选值包括normal和italic。默认值为normal |
bevelthickness | 否 | 该属性指定斜角的深度。斜角是前后面和拉伸体之间的倒角。该值定义斜角进入图形的深度。默认值为10。 |
bevelsize | 否 | 该属性指定斜角的高度。默认值为8 |
bevelsegments | 否 | 该属性定义斜角的分段数。分段数越多,斜角越平滑。默认值为3 |
bevelenabled | 否 | 如果这个属性设置为true,就会有斜角。默认值为false |
curvesegments | 否 | 该属性指定拉伸图形时曲线分成多少段。分段数越多,曲线越平滑。默认值为4 |
steps | 否 | 该属性指定拉伸体被分成多少段。默认值为1 |
extrudepath | 否 | 该属性指定图形沿着什么路径拉伸。如果没有指定,则沿着z轴拉伸 |
material | 否 | 该属性定义的是前后面所用材质的索引。使用three.sceneutils.createmultimaterialobject函数来创建网格 |
extrudematerial | 否 | 该属性指定斜角和拉伸体所用材质的索引。如果想给前后面使用单独的材质,使用three.sceneutils.createmultimaterialobject函数来创建网格 |
uvgenerato | 否 | 当你给材质使用纹理时,uv映射确定纹理的哪一部分用于特定的面。使用uvgenerator属性,你可以传入自己的对象,该对象将为传入的图形创建的面创建uv设置。如果没有指定,则使用three.extrudegeometry.worlduvgenerator |
frames | 否 | frenet框架用于计算样条曲线的切线、法线和副法线。在沿extrudepath拉伸几何体时会用到这个属性。你不需要指定它,因为three.js提供了实现途径—three.tubegeometry.frenetframes,它也被用作默认值。 |
案例实现
首先将光影效果,场景相关的设置好。 然后开始配置gui
通过配置的相关属性可以调整样式相关属性。 所有准备工作做好以后,开始加载字体,并在字体加载完成后回调,生成字体模型。字体文件统一放在了assets/fonts/下面
changefont:function () { //创建loader进行字体加载,供后面的模型使用 var loader = new three.fontloader(); loader.load( 'assets/fonts/' + gui.fontname + '_' + gui.fontweight + '.typeface.json', function ( response ) { gui.font = response; gui.asgeom(); } ); }
字体加载完成以后,运行生成字体的方法,生成字体
asgeom: function () { // 删除掉原来的旧模型 scene.remove(text1); scene.remove(text2); // 重新创建模型 var options = { size: gui.size, height: gui.height, weight: gui.weight, font: gui.font, bevelthickness: gui.bevelthickness, bevelsize: gui.bevelsize, bevelsegments: gui.bevelsegments, bevelenabled: gui.bevelenabled, curvesegments: gui.curvesegments, steps: gui.steps }; text1 = createmesh(new three.textgeometry("learning", options)); text1.position.z = -100; text1.position.y = 100; scene.add(text1); text2 = createmesh(new three.textgeometry("three.js", options)); scene.add(text2); }
以下是案例的所有代码:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>title</title> <style type="text/css"> html, body { margin: 0; height: 100%; } canvas { display: block; } </style> </head> <body onload="draw();"> </body> <script src="https://johnson2heng.github.io/three.js-demo/lib/three.js"></script> <script src="https://johnson2heng.github.io/three.js-demo/lib/js/utils/geometryutils.js"></script> <script src="https://johnson2heng.github.io/three.js-demo/lib/js/controls/orbitcontrols.js"></script> <script src="https://johnson2heng.github.io/three.js-demo/lib/js/libs/stats.min.js"></script> <script src="https://johnson2heng.github.io/three.js-demo/lib/js/libs/dat.gui.min.js"></script> <script> var renderer; function initrender() { renderer = new three.webglrenderer({antialias: true}); //renderer.setclearcolor(new three.color(0xeeeeee, 1.0)); //设置背景颜色 renderer.setsize(window.innerwidth, window.innerheight); document.body.appendchild(renderer.domelement); } var camera; function initcamera() { camera = new three.perspectivecamera(45, window.innerwidth / window.innerheight, 1, 10000); camera.position.set(0, 200, 500); } var scene; function initscene() { scene = new three.scene(); } var light; function initlight() { scene.add(new three.ambientlight(0x404040)); light = new three.directionallight(0xffffff); light.position.set(1, 1, 1); scene.add(light); } function initmodel() { //轴辅助 (每一个轴的长度) object = new three.axeshelper(50); scene.add(object); } //生成模型 function createmesh(geom) { //设置当前的模型矩阵沿xy轴偏移,让图片处于显示中心 geom.applymatrix(new three.matrix4().maketranslation(-250, -100, 0)); // 创建法向量纹理 var meshmaterial = new three.meshnormalmaterial({ flatshading: three.flatshading, transparent: true, opacity: 0.9 }); // 创建一个线框纹理 var wireframemat = new three.meshbasicmaterial(); wireframemat.wireframe = true; // 创建模型 var mesh = three.sceneutils.createmultimaterialobject(geom, [meshmaterial, wireframemat]); return mesh; } //初始化性能插件 var stats; function initstats() { stats = new stats(); document.body.appendchild(stats.dom); } //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放 var controls; function initcontrols() { controls = new three.orbitcontrols(camera, renderer.domelement); // 如果使用animate方法时,将此函数删除 //controls.addeventlistener( 'change', render ); // 使动画循环使用时阻尼或自转 意思是否有惯性 controls.enabledamping = true; //动态阻尼系数 就是鼠标拖拽旋转灵敏度 //controls.dampingfactor = 0.25; //是否可以缩放 controls.enablezoom = true; //是否自动旋转 controls.autorotate = false; //设置相机距离原点的最远距离 controls.mindistance = 20; //设置相机距离原点的最远距离 controls.maxdistance = 10000; //是否开启右键拖拽 controls.enablepan = true; } //生成gui设置配置项 var gui; var text1,text2; function initgui() { //声明一个保存需求修改的相关数据的对象 gui = { size: 90, height: 90, bevelthickness: 2, bevelsize: 0.5, bevelenabled: true, bevelsegments: 3, curvesegments: 12, steps: 1, fontname: "helvetiker", fontweight:"bold", weight: "normal", font:null, style:"italics", changefont:function () { //创建loader进行字体加载,供后面的模型使用 var loader = new three.fontloader(); loader.load( 'assets/fonts/' + gui.fontname + '_' + gui.fontweight + '.typeface.json', function ( response ) { gui.font = response; gui.asgeom(); } ); }, asgeom: function () { // 删除掉原来的旧模型 scene.remove(text1); scene.remove(text2); // 重新创建模型 var options = { size: gui.size, height: gui.height, weight: gui.weight, font: gui.font, bevelthickness: gui.bevelthickness, bevelsize: gui.bevelsize, bevelsegments: gui.bevelsegments, bevelenabled: gui.bevelenabled, curvesegments: gui.curvesegments, steps: gui.steps }; text1 = createmesh(new three.textgeometry("learning", options)); text1.position.z = -100; text1.position.y = 100; scene.add(text1); text2 = createmesh(new three.textgeometry("three.js", options)); scene.add(text2); } }; var datgui = new dat.gui(); //将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值) datgui.add(gui, 'size', 0, 200).onchange(gui.asgeom); datgui.add(gui, 'height', 0, 200).onchange(gui.asgeom); datgui.add(gui, 'fontname', ['gentilis', 'helvetiker', 'optimer']).onchange(gui.changefont); datgui.add(gui, 'fontweight', ['regular', 'bold']).onchange(gui.changefont); datgui.add(gui, 'bevelthickness', 0, 10).onchange(gui.asgeom); datgui.add(gui, 'bevelsize', 0, 10).onchange(gui.asgeom); datgui.add(gui, 'bevelsegments', 0, 30).step(1).onchange(gui.asgeom); datgui.add(gui, 'bevelenabled').onchange(gui.asgeom); datgui.add(gui, 'curvesegments', 1, 30).step(1).onchange(gui.asgeom); datgui.add(gui, 'steps', 1, 5).step(1).onchange(gui.asgeom); //调用生成一次图形 gui.changefont(); } function render() { renderer.render(scene, camera); } //窗口变动触发的函数 function onwindowresize() { camera.aspect = window.innerwidth / window.innerheight; camera.updateprojectionmatrix(); render(); renderer.setsize(window.innerwidth, window.innerheight); } function animate() { //更新控制器 controls.update(); render(); //更新性能插件 stats.update(); requestanimationframe(animate); } function draw() { initrender(); initscene(); initcamera(); initlight(); initmodel(); initcontrols(); initstats(); initgui(); animate(); window.onresize = onwindowresize; } </script> </html>