最近在个人网站butterpig中实现了个性印章的在线设计功能,里面目前一共实现了有八九种个性印章的样式,并且还有六七种网络开源商用的网络字体类型。具体效果可以访问:个人印章在线设计查看。

印章的设计,其实原理非常简单,主要就是通过canvas画图技术。而且画的内容也非常简单基础,因此不在这里具体说明。

该功能的难点在于如何在前端加载第三方字体文件。众所周知,字体文件的格式一般有.ttf和.woff等,由于中文和英文的差异性,导致中文字体包的大小一般都比较大,一般都有好几M,更有几十M几百M的字体包文件。

所以如果把这些字体文件放在自己的云服务器中,用户访问的时候加载到用户的浏览器,那对于一些带宽很小的云服务器简直不可想象。因此最终想到通过cdn加速来加载字体。最终证明该方法效果很好,同时也不占用任何服务端资源。

具体的思路,就是讲字体文件都放到github中自己建的一个仓库中,然后通过jsdelivr来加速这个github仓库。因为jsdelivr本就是一个专门加速github中开源库的cdn,凡是我们放到github中并且公开的内容,都可以通过jsdelivr来作为cdn加速,非常的稳定和方便。具体的使用方法大家可以去jsdelivr的官网去看,非常简单,就是把url链接中的几个路径改成自己的仓库名称和文件名称就行了。

该功能还有个问题,就是如何得知字体文件是否加载完成,是否加载成功或者失败。必须在加载成功后,马上回调来渲染canvas才行。然后html5中的@font-face是在真正用到该字体的是否,才自动去后台加载的,并且也不知道是否加载完成,导致前台的显示混乱。因此这里使用一个叫做fontfaceobserver的开源库,这个库的作用就是专门监听前端是否加载完成了某个字体,通过它的监听,我们就知道用户选择的某种字体是否通过cdn加载完成,并在加载完成后调用渲染。

1
2
3
4
5
6
new FontFaceObserver("font family").load(null, 15 * 1000).then(() => {
//console.log('Font is available');
this.drawPreview()
}, () => {
console.log('Font is not available');
});

其中FontFaceObserver默认的字体加载超时时间是3秒,比较短,所以我们改成15秒以防万一,不过一般情况下,只要网速好,加载个几M的字体文件也就是瞬间而已。这样一来,个性印章工具的使用体验算是比较合理。