从写代码开始,中文导致的问题不计其数,本次也不例外。
WebGL里要显示中文有两种方式:
2D效果
新建一个Canvas写上中文,然后再添加到WebGL里,优点是不用额外加载特定字体,网页能用什么字体它就能用什么字体,而且只要使用普通DOM API刷新内容,WebGL里render后就能渲染最新。使用DOM方便调试维护。缺点是这种方式还是2D的方式,没有完全发挥3D的效果。3D效果
每一个字体都是一个3D模型,优点是完全发挥3D效果可以配合3D实现原理能做出很炫的效果,缺点是这种方式需要额外准备字体模型库,然后还要载入页面中。
这还要分两种情况:
- 静态展示型,这就好办,你需要多少个字就提前做好引入,没有任何问题。
- 动态展示型,展示的字体根据动态数据随时变换,这种情况就要额外处理了,这也是本文讨论的解决方案。
一个中文字体有通常常用的也有五六千个字,有不少网站可以让你把ttf字体转为WebGL里能用的path,但这个过程还是非常痛苦的,转一次耗时非常长,重要的是还不一定能用,可能有bug。测试几个字体文件后,居然发现只有隶书能用,整个字体文件三十多兆
图片超过1M都觉得大了,不要说这个31M的字体文件在网速多快的情况下如何秒下,这是根本不可能的,只能需要另外一种方法来解决。打开lisu_regular.typeface.js
文件,内容大部分都是每一个字的path,于是我认为可以把头尾摘出来,然后在需要哪个字体的时候预先向服务器端请求字体路径再描绘3D。
摘除字体path后的lisu_regular.typeface.js
if (_typeface_js && _typeface_js.loadFace) _typeface_js.loadFace({
"glyphs":{},
"cssFontWeight":"normal",
"ascender":1194,
"underlinePosition":-59,
"cssFontStyle":"normal",
"boundingBox":{"yMin":-255,"xMin":54.25,"yMax":1194,"xMax":1378.046875},
"resolution":1000,
"original_font_information":{
"postscript_name":"LiSu",
"version_string":"Version 3.01",
"vendor_url":"",
"full_font_name":"LiSu",
"font_family_name":"LiSu",
"copyright":"(C) Copyright Stone Co., 1996",
"description":"",
"trademark":"Trademark of Stone Co., Beijing",
"designer":"",
"designer_url":"",
"unique_font_identifier":"LiSu",
"license_url":"",
"license_description":"",
"manufacturer_name":"",
"font_sub_family_name":"Regular"
},
"descender":-196,
"familyName":"LiSu",
"lineHeight":1584,
"underlineThickness":13
});
摘除后的lisu_regular.typeface.js
只有1k大小,与之前的31M相比是不是舒服了很多,大家看看glyphs默认是一个字体path都没有的,我们向服务器端请求载入几个字体看看
我们把请求的数据改写_typeface_,于是_typeface_里就有了这几个字的path
然后再做一些优化,比如要向服务器端请求字体path之前,先把重复的字给去掉,再把glyphs已存在的字给去掉就ok了