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%能加載出中文字體,經本人親測。