three.js在场景中可以加载obj文件(OBJLoader),加载stl文件(STLLoader)
加载文件太大时可以将obj和stl等转化的json文件等。
本文讲解如何加载字体以及中文字体
之前用three.js写个加载3D立体文字效果,发现输入中文会返回“?”,后来发现three.js字体(examples\fonts)文件夹下的json文件中只有英文和一些符号的,没有中文。
例如:gentilis_bold.typeface.json 这个文件加载这个字体的时候如下代码
var loader = new THREE.FontLoader();//新建字体对象 //加载相应的字体,下面字体名和样式组成gentilis_bold.typeface.json 完整文件名 var fontName = "gentilis";//字体名 var fontWeight = "bold"; //加粗字体
var fontJsonUrl = 'examples/fonts/' + fontName + '_' + fontWeight + '.typeface.json'; //你的字体json路径,文件名规格随意
,
loader.load( fontJsonUrl, function ( response ) {
//注意response 这内容比较关键,是否能加载中文就看这个变量了,这个变量里面的glyphs,默认的几种只有英文 var options = { size: 30, //字号大小,一般为大写字母的高度 height: 10, //文字的厚度 weight: 'normal', //值为'normal'或'bold',表示是否加粗 font: response, //字体,默认是'helvetiker',需对应引用的字体文件 style: 'normal', //值为'normal'或'italics',表示是否斜体 bevelThickness: 1, //倒角厚度 bevelSize: 1, //倒角宽度 curveSegments: 30,//弧线分段数,使得文字的曲线更加光滑 bevelEnabled: true, //布尔值,是否使用倒角,意为在边缘处斜切 }; ////创建一个三维对象的文本作为一个单一的对象 text输入的文字 options 文字设置 var textGeo = new THREE.TextGeometry( text, options); textGeo.computeBoundingBox(); textGeo.computeVertexNormals(); var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x ); var material = new THREE.MultiMaterial([ new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } ), // front new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.SmoothShading } ) // side ]); //新建mesh,加入 mesh = new THREE.Mesh( textGeo, material ); mesh.position.x = centerOffset; mesh.position.y = 30; mesh.position.z = 0; mesh.rotation.x = 0; mesh.rotation.y = Math.PI * 2; meshGroup.push(mesh) ; //scene是实例化的场景,在场景中加入mesh scene.add( mesh ); });
上面的代码只能实现英文字体,下面将中文字体实现
所用工具:facetype.js-gh-pages(上传字体,可以找本地电脑控制面板中的字体库的字体(TTF)进行测试,不过找小一点的,太大了编辑器打开会崩溃)
我用的是 方正兰亭超细黑简体 1.6M挺小,可以打开下面工具地址,上传这个ttf后缀的字体文件,它将会下载一个.json的文件。
https://github.com/gero3/facetype.js.git 下载地址
http://gero3.github.io/facetype.js 远程地址
这个文件内容如下:(我数据可能不同,我忘记这个是那个字体的参数了,不过重要的是glyphs这个对象包含着所有的汉子,几万行啊,太多了我就只列出几个了)
{
"glyphs":{
"夔": {
"ha": 1389,
"x_min": 60,
"x_max": 1324,
"o": "m 60 949 l 819 949 q 998 1123 868 993 l 1015 1107 q 857 949 944 1031 l 1324 949 l 1324 922 l 700 922 q 684 868 694 906 q 667 814 673 830 l 873 814 l 873 385 l 515 385 l 515 814 l 640 814 q 656 868 646 830 q 673 922 667 906 l 60 922 l 60 949 m 1020 244 l 1020 217 q 727 16 906 98 q 1318 -98 944 -49 l 1313 -125 q 689 0 928 -76 q 81 -141 467 -76 l 76 -119 q 656 16 467 -49 q 418 163 515 76 q 385 141 407 157 q 195 33 260 65 l 184 60 q 597 353 450 190 l 618 336 q 526 244 575 293 l 1020 244 m 982 814 l 1248 814 l 1248 602 l 1009 602 l 1009 510 q 1090 434 1004 429 l 1188 434 q 1291 494 1297 429 q 1297 564 1297 526 l 1324 559 q 1318 488 1324 537 q 1188 407 1318 401 l 1090 407 q 982 510 982 407 l 982 814 m 488 217 q 467 201 483 212 q 439 179 450 190 q 689 27 543 92 q 982 217 852 92 l 488 217 m 1221 787 l 1009 787 l 1009 624 l 1221 624 l 1221 787 m 304 863 l 331 863 l 331 694 l 456 694 l 456 667 l 331 667 l 331 456 l 472 477 l 477 450 l 65 396 l 65 423 l 141 434 l 141 749 l 168 749 l 168 434 l 304 456 l 304 863 m 543 787 l 543 678 l 846 678 l 846 787 l 543 787 m 543 651 l 543 543 l 846 543 l 846 651 l 543 651 m 543 412 l 846 412 l 846 515 l 543 515 l 543 412 m 998 331 l 1015 358 l 1324 179 l 1313 157 l 998 331 m 60 184 q 363 363 206 250 l 380 342 q 71 157 244 239 l 60 184 m 374 1107 l 391 1123 l 532 987 l 510 966 l 374 1107 z "
},
"中":{
"ha": 1389,
"x_min": 60,
"x_max": 1324,
"o": "m 60 949 l 819 949 q 998 1123 868 993 l 1015 1107 q 857 949 944 1031 l 1324 949 l 1324 922 l 700 922 q 684 868 694 906 q 667 814 673 830 l "
}
},
"cssFontWeight": "normal",
"ascender": 1189,
"underlinePosition": -100,
"cssFontStyle": "normal",
"resolution": 1000,
"descender": -334,
"familyName": "default",
"lineHeight": 1522,
"underlineThickness": 50
}
有了这个json文件就好办了,把上面的fontJsonUrl变量换成这个json地址就好了,这样是直接把整个json文件加载出来,可能有点慢,毕竟文件大。
加载慢的优化方案有:
1.弄个默认的json文件,把glyphs对象数组清空( "glyphs":{} ),在加载之前请求接口,接口返回该输入字体的glyphs下的字体数据对象,让把对象追加到glyphs里
面,就不用加载全部的了。
按照这方法100%能加载出中文字体,经本人亲测。