Text position on canvas is different in FireFox and Chrome Text position on canvas is different in FireFox and Chrome google-chrome google-chrome

Text position on canvas is different in FireFox and Chrome


Cause

As @iftah says: This mis-alignment is caused by a Firefox bug.

Please add your voice to the Firefox's bug page so they fix it soon.

Workaround

(Unfortunately), The workaround is to draw the text on a second canvas and scan that pixel data to find the topmost & leftmost pixel of the text.

Then draw the text on the main canvas but pulled upward and leftward by the calculated pixel offsets.

Here is annotated code and a Demo:

// canvas varsvar canvas=document.getElementById("canvas");var ctx=canvas.getContext("2d");var cw=canvas.width;var ch=canvas.height;// test varsvar 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});}
body{ background-color: ivory; }#canvas{border:1px solid red; margin:0 auto; }
<h4>Text drawn exactly at specified X,Y</h4><canvas id="canvas" width=300 height=200></canvas>


You can fix it easily.

you can use textBaseline = "middle";and must use transform to 50px of top

means:

    <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 = "middle";          ctx.font = '100px Arial';          ctx.textAlign = 'left';          ctx.fillStyle = 'rgba(0, 0, 0, 1)';          ctx.save();          ctx.transform(1, 0, 0, 1, 0, 50);          ctx.fillText('Test', 0, 0);          ctx.restore();       }    </script>

A another bug is in your code: rgba(0, 0, 0, 255)fourth number in rgba must be between 0-1 for example 0.75.

why I write .save() and .restore() ?for reset transform and clear after use it.

Of course you can use

ctx.fillText('Test', 0, 50);

Instead

ctx.save();ctx.transform(1, 0, 0, 1, 0, 50);ctx.fillText('Test', 0, 0);ctx.restore();


This appears to be a bug in Firefox dating back to 2012 and still not fixed!

See https://bugzilla.mozilla.org/show_bug.cgi?id=737852

Edit: Setting the baseLine to "alphabetic" (the default) results in both Chrome and Firefox having the same vertical location for the text.

Edit: Unfortunately, the vertical location isn't the only difference between Firefox and Chrome. Changing the string to "Testing" shows clearly that not only is the vertical location different, but also the space between the letters is slightly different - resulting in different width of the text.

If you really must have pixel perfect location AND size of the text maybe you should use Bitmap fonts