对于canvas.font = FontSize“px Arial”;其中FontSize是(8.1,8.2,8.3,…)我期望得到线性结果,但是唯一一直存档的浏览器是IE! ( 我知道 ). Firefox的收益率低于11.2px但超出此水平. Chrome和Safari仅将字体缩放为整数值.
舍入规则似乎设置为像素并向下舍入到最接近.5的整数
我的画布应用程序正在执行一些程序化的动画变换(缩放和翻译)为了提高效率,尽量避免画布变换,虽然我怀疑它会解决问题,但我也没有通过设置html文本大小仅用CSS3来测试这个Canvas.font假设是根据规范)
浏览器在pt,px,em和%字体大小之间的行为至少是一致的. [编辑:除了Safari不会渲染%尺寸]
[旁白:所有字体看起来有点大胆一度炸毁了一下.当我们从17.4px变为17.5px时,Safari会拿出那块蛋糕.BAMB!]
我在下面附上了一些示例图片,但是我们真的想要了解如何让所有浏览器更像IE的想法(再也没想过我会这么说) – 这是一个bug还是渲染字体的标准?
这是我的测试代码,可以复制PX字体大小的情况.
<!DOCTYPE html><html><head><script> function display() { var canvas = document.getElementById('test'); // For EM and % cases.... //canvas.style.font="5px Arial"; canvas.height = 1000; var context = canvas.getContext('2d'); var minSize = 10; var lineHeight = 100; for(var a=minSize; a< 20; a+=0.1) { var font_size = Math.round(a*10000)/10000; context.font = a + "px Arial"; context.fillText("A: EXAMPLE TEXT > " + font_size,20,(font_size-minSize)*lineHeight); } } </script></head><body onload="display()"><canvas id="test"></canvas></body></html>
像素比例
点量表
em scale – 1em = 5px Arial
百分比 – 100%= 5px Arial
解决方法
回顾一下(因为在问题中也不清楚)我试图通过一些浮点数来增加字体大小以放大和缩小文本.但由于大多数字体大小为最接近的整数值,因此导致抖动结果.
所以举个例子.
var zoom = 1.02; var font_size = 12; context.font = (font_size * zoom) + "px Arial"; // 12.24px
zoom = 1.04(12.48px)将呈现与上面的代码相同,而zoom = 1.06(12.75px)将向上舍入到13px.
这导致值之间非常不希望的字体大小跳跃,而画布上的所有其他元素都正确缩放.
所有浏览器都呈现给定的文本字符串,如“EXAMPLE TEXT”和略有不同的长度,这个问题更加复杂.
解决方案
在初始化期间以标准字体大小(缩放= 1)渲染文本并测量行长度,让此值称为iniLineLength
在场景渲染过程中,我使用隐藏的画布将文本渲染到当时使用的drawImage到主画布上,并在宽度上使用乘数.
tmpContext.font = (font_size * zoom) + "px Arial"; tmpContext.fillText(MyLineOfText,0); var s = (iniLineLength * zoom) / tmpContext.measureText(MyLineOfText) ; mainContext.drawImage(tmpCanvas,x,y,pw * s,ph);
根据行长度与预期行长度的距离,在主画布上拉伸或缩小生成的文本行.
在理想世界中,s总是等于1,因为预期的线长总是与实际的线长相同.预期的行长度是我们的样本行长度iniLineLength乘以我们的字体大小在此渲染过程中的相同缩放因子.
我对这一切的奖励是,它具有规范浏览器行为的所有差异的效果……差不多.
问题
即使行长度归一化,行中每个字符的确切位置也不相同.在下图中给出效果.
然而,这已经是我所拥有的巨大改进.
此外,你想要将你的tmpCanvas剪辑到mainCanvas,否则你的浏览器会在尝试创建和复制你的百万像素文本时停下来,只是为了让一个角色全屏显示.
考虑到这一点,您还可以根据需要设置您的tmp画布宽度和高度,以适应您要渲染的实际文本行,这将节省内存,时间等.