我开发了一个星露谷风格的卡片生成器小程序,遇到最麻烦的问题就是字体的处理。微信小程序的字体处理存在诸多限制,尤其是真机环境兼容性问题,有时候在开发工具上一切都好,一上手机啥效果也没了。为了解决这些问题,主要参考了https://juejin.cn/post/7252175375105916965#heading-7这篇文章的解决办法。
微信小程序字体加载限制
问题:wx.loadFontFace没有缓存机制,用户每次打开小程序,都要重新下载字体文件。我买的阿里云oss的下行流量包,如果每次都要重新下载字体文件,有点小贵。。。
解决方案:
- 使用
wx.loadFontFace
API加载字体 - 将字体文件转换为base64格式存储
- 实现字体缓存机制,避免重复下载
1 | // 使用loadFontFace加载字体 |
OpenType.js 集成
如果直接用canvas画下载好的字体,在开发工具上显示是正常的,但在真机测试的时候,渲染出的canvas的字体退回到了系统自带。微信团队好像还是没有解决这个问题。遂参考他人用OpenType.js库解决。
字体解析与缓存
OpenType.js是一个强大的字体处理库,可以将字体文件解析为可操作的JavaScript对象。
1 | // 字体解析核心代码 |
字体绘制实现
OpenType.js的核心优势在于可以将文字转换为路径对象,然后通过Canvas API进行绘制。
1. 带阴影的字体绘制
1 | drawTextWithOpenType(ctx, text, x, y, fontSize, color = '#1a1a1a', fontWeight = 'normal') { |
2. 粗体效果实现
由于微信小程序环境的限制,在真机测试时还是无法直接使用字体的粗体变体(也没搞懂为什么)。通过多次绘制模拟粗体效果:
1 | // 真机兼容的粗体实现 |
3. 文本换行处理
对于长文本,实现了自动换行功能:
1 | wrapTextWithOpenType(ctx, text, x, y, maxWidth, lineHeight, color = '#2F1B14') { |
双层缓存系统设计
文件缓存层
为了减少网络请求和提高加载速度,实现了文件缓存:
1 | // 字体缓存系统 |
内存缓存层
最开始用上面的方法,切换还是太慢了,换一个字体要十秒钟。。。还是先加载到内存缓存快一些:
1 | // 内存缓存系统 |
九宫格边框实现
为了实现星露谷风格的边框效果,使用了九宫格技术:
1 | // 九宫格边框绘制 |
动态属性绘制
对于卡片的属性部分,实现了动态绘制功能:
1 | // 绘制动态属性 |
性能优化策略
字体加载优化
1 | // 预加载策略 |
内存管理优化
1 | // 字体缓存管理 |
错误处理与降级
1 | // 完善的错误处理机制 |
第一次碰前端相关,写WXML和WXSS用Cursor真的省去了很多重复劳动!我只需要聚焦于底层逻辑还有优化就可以了,把组织容器布局交给AI来做就好。