html2canvas 文字向下偏移兼容方法
最近做项目遇到转海报的功能,调试好的页面发现部分机型,主要是ios15以上新机型会有适配问题,文字向下偏移。
搜索了几篇文章都说是因为字号,字体的问题:
但是我们已经强制使用了同样的字体,不同设备之间还是会有一些差异比如下图:
通过样式是调整不好了,因为我们发现一个机型ok了,另外一个机型就不正常,不同的机型非海报部分的样式都是没问题的。
最后debug了一下html2canvas的源码看了一下他内部绘制文字的逻辑:
比较关键的部分是renderTextNode,所有文本的绘制都会走,然后通过getMetrice获取文本的样式,再进行最后的canvas的绘制操作。
看了一下不同设备中,是baseline那个属性导致的差异过大,文本无法对齐。所以看了一下baseline的计算方式:
首先html2canvas每操作一个字体和字号的文本时都会内部保存一份,遇到相同的直接复用缓存,那么是怎么计算的呢?
代码我稍微改了改,原理其实比较简单,就是弄了个空div,先插入一个span,给赋值上需要绘制的字号,字体,然后再插入一张1x1的图片,设置display block,然后通过offsetTop的差值来计算基线,公式是注释的那一行:
// var baseline = img.offsetTop - span.offsetTop +2;
var baseline = parseInt(getComputedStyle(span,null).lineHeight,10) - 5;
计算出行高再+2就可以了,文本绘制时的baseline是:
this.ctx.textBaseline = 'alphabetic';
然后我就发现不同设备下,这个img和span的offsetTop差值能差到1倍以上,开始我觉得无解了,后来突然觉得特么的我不用他这个方法,我直接用行高加一个base值也能算出来baseline啊,这个问题的核心在于修好了一个设备,另外一个设备就会出错,所以无法完美兼容所有设备,那么我绕过去现在有兼容的计算方法就可以了。
所以修改了这一行后,三台不一样的设备就都好了。世界终于安静了。
最后祝大家世界杯看球愉快。。。