Paper.JS初始化无法加载自定义字体的跨浏览器问题求助
问题分析与解决:PaperJS自定义字体在Chrome/Edge需resize才显示
问题原因
- 隐藏div无法触发字体加载:你使用的
display: none元素在Chrome/Edge的渲染逻辑中不会触发字体下载——浏览器判定不可见元素不需要加载对应字体,所以这个初始化方法无效。 - 绘制时机早于字体加载:代码在页面加载后立即执行PaperJS绘制,但此时Roboto Mono字体还未加载完成,Chrome/Edge会用默认字体渲染Canvas文本;而窗口resize时会触发PaperJS的自动重绘,这时候字体已经加载完毕,所以能显示正确样式。Firefox对字体加载的处理逻辑不同,会提前加载或优先处理Canvas用到的字体,因此能正常显示。
解决方法
方法1:用可见但不可感知的元素触发字体加载
把原来的隐藏div改成存在布局但用户不可见的元素,同时添加一个字符(空元素可能仍不触发加载),确保浏览器加载目标字体:
<!-- 触发字体加载的元素 --> <div style="visibility: hidden; position: absolute; left: -9999px; font-family: 'Roboto Mono'; font-weight: bold;">x</div> <!-- 画布 --> <canvas id="mycanvas" resize></canvas>
visibility: hidden保留元素布局,position: absolute不占用页面空间,添加字符x明确告知浏览器需要加载该字体的对应字重。
方法2:监听字体加载完成后再绘制
使用浏览器的FontFaceSet API,等待目标字体完全加载后再执行PaperJS绘制代码,从根源避免时机问题:
// 精确监听Roboto Mono的bold 30px字体加载完成 document.fonts.load('bold 30px "Roboto Mono"').then(function() { canvasElem = $('#mycanvas').get(0); paper.install(window); paper.setup(canvasElem); var text = new paper.PointText(new paper.Point(50, 50)); text.justification = 'center'; text.fillColor = 'red'; text.fontFamily = 'Roboto Mono'; text.fontSize = '30px'; text.fontWeight = 'bold'; text.content = 'This is a test 1234567890'; paper.view.draw(); });
如果要等待所有字体加载完成,也可以用document.fonts.ready.then(...),但精确监听目标字体更高效。
方法3:手动触发重绘(备选方案)
如果无法修改绘制时机,可以在字体加载完成后手动调用PaperJS的重绘方法,但需要确保字体已经加载:
// 先执行原绘制代码 canvasElem = $('#mycanvas').get(0); paper.install(window); paper.setup(canvasElem); var text = new paper.PointText(new paper.Point(50, 50)); text.justification = 'center'; text.fillColor = 'red'; text.fontFamily = 'Roboto Mono'; text.fontSize = '30px'; text.fontWeight = 'bold'; text.content = 'This is a test 1234567890'; paper.view.draw(); // 字体加载完成后重绘 document.fonts.load('bold 30px "Roboto Mono"').then(function() { paper.view.draw(); });
这个方法是补漏方案,不如前两种可靠,优先推荐前两个方法。
内容的提问来源于stack exchange,提问作者gene b.
相关产品推荐
相关产品推荐

