最近接到一个需求,需要在微信小程序中做出用户可自定义缩放旋转图片和文字定制功能,开发使用 uni-app,这里记录开发中遇到的几个问题。
一、canvas设置字体大小的数值需为整数使用 canvas 渲染文字时,需要设置文字的字体。
let ctx = uni.createCanvasContext('canvas') ctx.font = '16px Arial' // 设置成功 ctx.font = '16.66px Arial' // 这样写会触发警告,不生效二、字体集font-family兼容的问题微信小程序中,对于文字字体集的兼容性很差。
IOS 端目前发现只有三种字体能设置成功('Arial', 'Courier New', 'Georgia')。
而 Android 端只有两种字体('serif', 'noto'),且 Android 端设置这两种字体只会在 canvas 中生效,在 DOM 中直接对文本设置这两种字体,没有任何变化。另外,在旧手机(非近一年内发布的新型号)上只会对英文生效。
针对以上问题,有两条路可以走:
一是直接重写一个 H5 页面,使用 webview 内嵌到小程序中(重写太繁琐);
二是按原路继续走,多做些兼容操作。
博主选了第二条路。IOS 端可以不理,系统对那三种字体基本兼容(针对英文)。
但对于Android端,博主首先是使用 uni.loadFontFace 尝试去引入 'serif', 'noto' 这两种字体供 DOM 渲染使用,但即便将字体挂到自己的 OSS 存储系统上进行加载,仍然没有效果。

无奈,只能将 .ttf 字体文件转为 base64 引入,只保留英文后的两种字体加载下来,整个包大小只增加了 60KB。
参考链接:Android 系统字体规范
(https://www.xueui.cn/download/font-download/android-font-down.html)
Noto 字体下载
Noto sans字体免费下载和在线预览-字体天下
字体文件转base64
Online @font-face generator — Transfonter
在线字体提取网站在线字体提取工具,字体子集生成器 - 在线工具 - 字客网
将处理完需导入的字体放到 CSS 文件中,判断系统为 Android 时导入:
judgeSystem() { let system = uni.getSystemInfoSync().system // 系统信息 this.judgeTextHasCN() // 判断文字中是否存在中文(因设置字体只对英文生效) if (system.includes('Android')) { require('@/common/css/android-font.css') this.textFamilyList = ['serif', 'noto'] this.fontFamily = 'serif' } else { // 其他平台其实还包括windows this.textFamilyList = ['Arial', 'Courier New', 'Georgia'] this.fontFamily = 'Arial' } }经过 base64 后的字体 CSS 大概长这样:
@font-face { font-family: 'serif'; src: url('data:font/truetype;charset=utf-8;base64,AAEAAAAQAQAABAAARkZUTVq0Nk4AAG...') font-weight: normal; font-style: normal; font-display: swap; }总结不同平台对于字体的兼容都不同,其实最完美的方法还是使用 webview。
如果需要对中文也兼容,那还需引入相应的中文字体集,不过全部引入会导致包体积过大。但也有相应的方法,就是动态地对需要的文字做抽离,只引需要的文字,有机会下次再展开聊聊。
下期继续给大家分享uni-app实战中的点点滴滴,敬请期待~
欢迎各位关注、留言,大家的支持就是我的动力!
制图网(www.makepic.net),专业的logo免费设计在线生成网站,全自动智能化logo设计,商标设计,logo在线生成!
欢迎使用制图网制作属于您公司自己的logo,不仅专业而且经济实惠,全方位满足您公司品牌化、视觉化的需求。
只需简单一步,使用微信扫码(或长按识别二维码)并在任一小程序首页根据提示获取激活码!
chatGPT中文网页版,无需注册,快来体验全网最火爆的人工智能应用!
只需简单一步,使用微信扫码(或长按识别二维码)并在任一小程序首页根据提示获取激活码!
chatGPT中文网页版,无需注册,快来体验全网最火爆的人工智能应用!