画布上的文字位置在FireFox和Chrome中是不同的

Lev*_*Lev 5 javascript firefox html5 google-chrome html5-canvas

我需要在HTML5画布上的精确位置绘制文本字符串.

这是我的测试代码:

<!DOCTYPE html>
<html>
<body>
<canvas id="mainCanvas" width="320" height="240" style = "border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
   window.onload = function() {
      var canvas = document.getElementById("mainCanvas");
      var ctx = canvas.getContext("2d");      
      ctx.textBaseline = "top";
      ctx.font = '100px Arial';
      ctx.textAlign = 'left';
      ctx.fillStyle = 'rgba(0, 0, 0, 255)';
      ctx.fillText('Test', 0, 0);
   }
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Chrome和Firefox顶部的边距不同: Chrome与Firefox中的文字

我将在画布上绘制其他元素(例如图像,形状),并且我需要确保文本出现在所有浏览器中的相同位置.可能吗?

mar*_*rkE 10

原因

正如@iftah所说:这种错误对齐是由Firefox错误引起的.

请将您的声音添加到Firefox的错误页面,以便他们尽快修复.

解决方法

(不幸的是),解决方法是在第二个画布上绘制文本并扫描该像素数据以找到文本的最顶部和最左边的像素.

然后在主画布上绘制文本,但是通过计算的像素偏移向上和向左拉动.

这是带注释的代码和演示:

// canvas vars
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// test vars
var text='Test';
var fontsize=100;
var fontface='arial';

drawTextAtXY(0,0,text,fontsize,fontface,'black');

function drawTextAtXY(x,y,text,fontsize,fontface,fill){
    // find the leftmost & topmost pixel of the text
    var minXY=getTextTop(text,fontsize,fontface);
    // set the font styles
    ctx.textBaseline='top';
    ctx.font=fontsize+'px '+fontface;
    ctx.fillStyle=fill;
    // draw the text
    // Pull the text leftward and topward by minX & minY
    ctx.fillText(text,x-minXY.x,y-minXY.y);
}


function getTextTop(text,fontsize,fontface){
    // create temp working canvas
    var c=document.createElement('canvas');
    var w=canvas.width;
    var h=fontsize*2;
    c.width=w;
    c.height=h;
    var cctx=c.getContext('2d');
    // set font styles
    cctx.textBaseline='top';
    cctx.font=fontsize+'px '+fontface;
    cctx.fillStyle='red';
    // draw the text
    cctx.fillText(text,0,0);
    // get pixel data
    var imgdata=cctx.getImageData(0,0,w,h);
    var d=imgdata.data;
    // scan pixel data for minX,minY
    var minX=10000000;
    var minY=minX;
    for(var y=0;y<h;y++){
    for(var x=0;x<w;x++){
        var n=(y*w+x)*4
        if(d[n+3]>0){
            if(y<minY){minY=y;}
            if(x<minX){minX=x;}
        }
    }}
    // return the leftmost & topmost pixel of the text
    return({x:minX,y:minY});
}
Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
Run Code Online (Sandbox Code Playgroud)
<h4>Text drawn exactly at specified X,Y</h4>
<canvas id="canvas" width=300 height=200></canvas>
Run Code Online (Sandbox Code Playgroud)


Ift*_*tah 2

这似乎是 Firefox 中的一个错误,可以追溯到 2012 年,但仍未修复!

请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=737852

编辑: 将基线设置为“字母”(默认)会导致 Chrome 和 Firefox 具有相同的文本垂直位置。

编辑: 不幸的是,垂直位置并不是 Firefox 和 Chrome 之间的唯一区别。将字符串更改为“Testing”清楚地表明,不仅垂直位置不同,而且字母之间的间距也略有不同 - 导致文本宽度不同。

如果您确实必须拥有像素完美的位置和文本大小,也许您应该使用位图字体