如何修复Canvas填充土耳其语字符ğ时首次渲染乱码的问题
问题根因
- 该问题和UTF-8字符集无关,是Google Fonts的按需加载机制导致的:Roboto字体默认拆分了多个字符子集,土耳其语的
ğ等特殊字符属于latin-ext子集,默认不会提前加载。 - 你调用的
document.fonts.load方法如果不传第二个参数(待检测的文本),仅会校验基础拉丁字符的字体是否加载完成,首次渲染时特殊字符对应的字体子集还未返回,所以出现乱码;第二次点击时对应字符的字体子集已经加载完成,因此显示正常。
修复方案
方案1:加载字体时明确传入待渲染文本(推荐)
在调用document.fonts.load时把要渲染的姓名、职位文本作为第二个参数传入,强制字体加载接口校验这些特殊字符对应的字体是否加载完成,没加载完成就不会触发后续的canvas绘制逻辑。
修改后的JS代码如下:
$("#formButton").click(function() { var name = $("#formName").val(); var title = $("#formTitle").val(); // 合并待渲染文本,传入load方法做校验 var renderText = name + title; Promise.all([ document.fonts.load("700 32px Roboto", renderText), document.fonts.load("300 20px Roboto", renderText), ]).then(() => { var canvas = document.getElementById("canvas-top"); var ctx = canvas.getContext("2d"); // 绘制前清空画布,避免多次点击内容叠加 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.font = "700 32px Roboto"; ctx.fillStyle = "#1F5890"; ctx.fillText(name, 15, 80); ctx.font = "300 20px Roboto"; ctx.fillStyle = "#1F5890"; ctx.fillText(title, 15, 105); }); console.log(name, title); });
方案2:预加载拉丁扩展字符集
在引入Google Fonts的链接中追加subset=latin-ext参数,提前加载包含土耳其语等特殊字符的字体子集,不需要修改JS逻辑即可解决问题。
修改后的HTML字体引入代码如下:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;500;700&display=swap&subset=latin-ext" />
效果对比
- 异常效果:

- 正常效果:

内容的提问来源于stack exchange,提问作者sociolog
相关产品推荐
相关产品推荐

