分数字体大小html5画布?

分数字体大小html5画布?,html,animation,canvas,fonts,scale,Html,Animation,Canvas,Fonts,Scale,我有一个问题,不同的浏览器如何在HTML5画布上呈现字体大小。特别是字体大小不是整数的地方。例如“8.5px Arial”、“2.23em Arial”等 对于canvas.font=FontSize+“px Arial”;如果FontSize是(8.1,8.2,8.3,…),我希望得到一个线性结果,但是唯一一个一贯存档的浏览器是IE!(我知道)。Firefox在11.2px以下,但在11.2px以上是线性的。Chrome和Safari仅将字体缩放为整数值 舍入规则似乎设置为像素,并向下舍入到下

我有一个问题,不同的浏览器如何在HTML5画布上呈现字体大小。特别是字体大小不是整数的地方。例如“8.5px Arial”、“2.23em Arial”等

对于canvas.font=FontSize+“px Arial”;如果FontSize是(8.1,8.2,8.3,…),我希望得到一个线性结果,但是唯一一个一贯存档的浏览器是IE!(我知道)。Firefox在11.2px以下,但在11.2px以上是线性的。Chrome和Safari仅将字体缩放为整数值

舍入规则似乎设置为像素,并向下舍入到下面最接近的整数。5

我的canvas应用程序正在执行一些编程动画转换(缩放和平移),试图避免画布转换以提高效率,尽管我怀疑这会解决问题,但我也没有通过仅使用CSS3设置html文本大小来测试这一点(canvas.font应该基于规范)

浏览器在pt、px、em和%字体大小之间的行为至少是一致的。[编辑:Safari除外不呈现%sizes]

[旁白:所有字体放大后看起来都有点粗体。Safari将蛋糕从17.4px增加到17.5px。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>

函数显示(){
var canvas=document.getElementById('test');
//对于EM和%案例。。。。
//canvas.style.font=“5px Arial”;
画布高度=1000;
var context=canvas.getContext('2d');
var minSize=10;
var线宽=100;
对于(var a=minSize;a<20;a+=0.1)
{
var font_size=数学四舍五入(a*10000)/10000;
context.font=a+“px Arial”;
context.fillText(“A:示例文本>”+字体大小,20,(字体大小)*线宽);
}
}
像素尺度 点标度 em刻度-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

这导致字体大小在值之间出现非常不希望的跳跃,而画布上的所有其他元素都已正确缩放

所有浏览器都呈现一个给定的文本字符串,如“示例文本”,长度略有不同,这一事实使问题更加复杂

解决方案 在初始化过程中,以标准字体大小(zoom=1)呈现文本并测量行长,将此值称为iniLineLength

在场景渲染期间,我使用了一个隐藏的画布来渲染文本,然后使用drawImage将文本渲染到主画布上,宽度上有一个倍增

tmpContext.font = (font_size * zoom) + "px Arial";
tmpContext.fillText(MyLineOfText,0, 0); 
var s = (iniLineLength * zoom) / tmpContext.measureText(MyLineOfText) ;
mainContext.drawImage(tmpCanvas,x, y, pw * s, ph);
生成的文本行在主画布上根据行长度与预期行长度的距离拉伸或收缩

在理想情况下,s始终等于1,因为预期的线长度始终与实际线长度相同。预期的线条长度是我们的采样线条长度inLineLength乘以与此渲染过程中字体大小相同的缩放因子

这一切的好处是,它可以规范化浏览器行为中的所有差异。。。差不多

问题 即使行长标准化,行中每个字符的确切位置也不相同。在下图中给出效果

然而,这已经是一个巨大的进步,我有

此外,您还需要将您的tmpCanvas剪辑到mainCanvas,否则您的浏览器将在尝试创建和复制百万像素的文本时陷入停顿,这仅仅是为了实现一个字符的全屏显示

考虑到这一点,您还可以根据需要设置tmp画布的宽度和高度,以适合要渲染的实际文本行,这将节省内存、时间等