簡體   English   中英

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

[英]Text position on canvas is different in FireFox and Chrome

我需要在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>

Chrome和Firefox頂部的邊距不同: Chrome與Firefox中的文字

我將在畫布上繪制其他元素(例如圖像,形狀),並且我需要確保文本出現在所有瀏覽器中的相同位置。 可能嗎?

原因

正如@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}); } 
 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> 

你可以輕松修復它。

你可以使用textBaseline =“middle”; 並且必須使用變換到50px的頂部

手段:

    <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>

甲另一個錯誤是在代碼:RGBA(0,0,0,255)在第四RGBA數必須是0-1之間,例如0.75。

為什么我寫.save()和.restore()? 用於重置轉換並在使用后清除它。

當然可以使用

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

代替

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

這似乎是Firefox中可以追溯到2012年的一個錯誤,但仍然沒有修復!

請參閱https://bugzilla.mozilla.org/show_bug.cgi?id=737852

編輯:將baseLine設置為“字母”(默認)會導致Chrome和Firefox具有相同的文本垂直位置。

編輯:不幸的是,垂直位置並不是Firefox和Chrome之間的唯一區別。 將字符串更改為“測試”清楚地表明,不僅垂直位置不同,而且字母之間的空間也略有不同 - 導致文本的寬度不同。

如果你真的必須有像素完美的位置和文本大小可能你應該使用位圖字體

正如其他答案中所述,它是bug的一個王者(或者可能只是一個不同的實現)。 textBaseline bottom和Y位置為100可以修復它。

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

通常:使用基線底部並增加字體大小量的Y位置

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM