2016-03-11 18 views
5

Potrzebuję narysować ciąg tekstowy na dokładnej pozycji na kanwie HTML5.Pozycja tekstu na płótnie różni się w FireFox i Chrome

Here's my test code:

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

Margines na górze jest inna w Chrome i Firefox: Text in Chrome vs Firefox

mam zamiar wyciągnąć inne elementy (np obrazy, kształty) na płótnie, a Muszę się upewnić, że tekst pojawia się w tej samej pozycji we wszystkich przeglądarkach. Czy to możliwe?

+1

prawdopodobnie problem tkwi w wielkości tekstu, kiedy zmienił to będzie działać w porządku, chociaż próbowałem za pomocą poniżej i działa dobrze ze mną ctx.font = "50px Verdana"; ctx.fillStyle = 'rgba (0, 0, 0, 255)'; ctx.fillText ("Test", 10, 50); – cracker

+0

@cracker Próbowałem zmienić czcionkę zgodnie z sugestią, a pozycja tekstu względem górnej części kanonu wciąż jest inna w Chrome i Firefox – Lev

+0

Próbowałem używać ctx.textBaseline = "alphabetic"; ctx.fillText ("Test", 10, 100); gdzie trzeba ręcznie ustawić parametry. może ci pomóc! – cracker

Odpowiedz

2

Wygląda na to, że błąd w Firefoksie sięga roku 2012 i wciąż nie został naprawiony!

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

Edit: Ustawianie początku badania do „alfabetyczne” (domyślna) powoduje zarówno Chrome i Firefox o tej samej pionowej miejsce dla tekstu.

Edytuj: Niestety, położenie w pionie nie jest jedyną różnicą między Firefoksem a Chrome. Zmiana ciągu znaków na "Testowanie" pokazuje wyraźnie, że nie tylko położenie w pionie jest inne, ale także odstęp między literami jest nieco inny - co powoduje różną szerokość tekstu.

Jeśli naprawdę musi mieć pikseli doskonałą lokalizację i wielkość tekstu może trzeba zastosować Bitmap fonts

10

Przyczyna

Jak @iftah mówi: Ta mis-wyrównanie jest spowodowany przez Firefox bug.

Dodaj swój głos do strony błędu Firefoksa, aby wkrótce rozwiązać problem.

Obejście

(Niestety) Rozwiązaniem jest zwrócenie tekst na drugim płótnie i skanowania, dane pikseli znaleźć najwyższą & skrajnie lewą piksel tekstu.

Następnie narysuj tekst na głównym płótnie, ale pociągnięty w górę i w lewo o wyliczone przesunięcia pikseli.

Tutaj jest odnotowany kod i Demo:

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

+0

I chociaż tworzenie dużego obrazu strony chrome i ładowanie jej za pomocą mapy obrazu byłoby dużo pracy ... – ThrowingDwarf

+0

@ThrowingDwarf. Tak, zgodna z przeglądarką === dobra, (niekompatybilna z przeglądarkami || trzaskami przeglądarki) === PITA. :-) – markE

+1

Trochę aktualizacji na ten temat (raport o błędzie w końcu wrócił do życia :-)): To może być błąd w innych przeglądarkach https://bugzilla.mozilla.org/show_bug.cgi?id=737852# c20 – Kaiido

3

Można je łatwo naprawić.

możesz użyć textBaseline = "middle"; i musi używać przekształcić do 50px najwyższej

oznacza:

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

kolejny błąd w kodzie: rgba (0, 0, 0,) numer czwarty w RGBA muszą być między 0-1 na przykład 0,75.

po co pisać .save() i .restore()? dla resetowania i kasowania po użyciu.

Oczywiście można użyć

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

Zamiast

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

Jak stwierdzono w innych odpowiedzi to jakiś król błąd (a może po prostu innej realizacji). textBaseline na dole i Y na 100 może to naprawić.

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

ogólnie: Korzystanie z bazowym dołu i zwiększyć pozycję Y kwotę rozmiar czcionki

Powiązane problemy