2016-03-11 4 views
5

Мне нужно нарисовать текстовую строку в точном месте на холсте HTML5.Текстовое положение на холсте отличается от FireFox и 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> 

Маржа на вершине отличается в Chrome и Firefox: Text in Chrome vs Firefox

я собираюсь рисовать другие элементы (например, изображения, формы) на холсте, и Мне нужно убедиться, что текст отображается в одной позиции во всех браузерах. Является ли это возможным?

+1

вероятно, проблема связана с текстом размера, когда я изменил это будет работать нормально, хотя я попытался с помощью ниже, и он отлично работает со мной. ctx.font = «50px Verdana»; ctx.fillStyle = 'rgba (0, 0, 0, 255)'; ctx.fillText («Тест», 10, 50); – cracker

+0

@cracker Я попытался изменить шрифт, как вы предложили, и положение текста относительно верхней части холста все еще отличается в Chrome и Firefox – Lev

+0

Я пробовал использовать ctx.textBaseline = "alphabetic"; ctx.fillText ('Test', 10, 100); где вам нужно вручную установить параметры. это может помочь вам! – cracker

ответ

2

Это, кажется, ошибка в Firefox, относящаяся к 2012 году и по-прежнему не исправлена!

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

Edit: Установка Baseline в "буквенный" (по умолчанию) приводит, как Chrome и Firefox с той же вертикали место для текста.

Редактировать: К сожалению, вертикальное расположение не является единственной разницей между Firefox и Chrome. Изменение строки на «Тестирование» ясно показывает, что не только вертикальное расположение отличается, но и пробел между буквами несколько отличается - в результате получается разная ширина текста.

Если вы действительно должны иметь пиксельный идеальное расположение и размер текста может быть, вы должны использовать Bitmap fonts

10

Причина

Как @iftah говорит: Это неправильно выравнивание вызвано Firefox bug.

Пожалуйста, добавьте свой голос на страницу ошибок 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>

+0

И я, хотя создаю большое изображение страницы хрома и загружая его с помощью карты изображений, будет много работы ... – ThrowingDwarf

+0

@ThrowingDwarf. Yep, совместимый с браузером === хорошо, (несовместимые с браузером || браузер-глюки) === PITA. :-) – markE

+1

Некоторое обновление об этом (отчет об ошибке, наконец, вернулся к жизни :-)): на самом деле это может быть ошибка в других браузерах https://bugzilla.mozilla.org/show_bug.cgi?id=737852# c20 – Kaiido

3

Вы можете исправить это легко.

Вы можете использовать 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,) четвёртое число в 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(); 
2

Как указано в другой ответ, это какой-король ошибки (или, возможно, просто другую реализацию). 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 количество размер шрифта

Смежные вопросы