Рисование текста с внешним штрихом с холстом HTML5

В настоящее время я использую HTML5 canvas для рендеринга нескольких строк с использованием метода fillText. Это прекрасно работает, но я также хотел бы дать каждой строке черный штрих 1px. К сожалению, функция strokeText, похоже, использует внутренний ход. Чтобы противостоять этому, я написал функцию drawStrokedText, которая достигает эффекта, которым я подвергаюсь. К сожалению, это ужасно медленно (по понятным причинам).

Существует ли быстрый, кросс-браузерный способ достижения 1px внешнего штриха с использованием встроенных функций холста?

drawStrokedText = function(context, text, x, y)
{
    context.fillStyle = "rgb(0,0,0)";
    context.fillText(text, x-1, y-1);
    context.fillText(text, x+1, y-1);
    context.fillText(text, x-1, y);
    context.fillText(text, x+1, y);
    context.fillText(text, x-1, y+1);
    context.fillText(text, x+1, y+1);

    context.fillStyle = "rgb(255,255,255)";
    context.fillText(text, x, y);
};

Вот пример эффекта на работе:

enter image description here

Ответ 1

Что случилось с инсультом? Поскольку половина хода будет за пределами формы, вы всегда можете сделать штрих с шириной линии, которую вы хотите. Поэтому, если вы хотите иметь 4px внешний ход, вы можете сделать:

function drawStroked(text, x, y) {
    ctx.font = "80px Sans-serif"
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 8;
    ctx.strokeText(text, x, y);
    ctx.fillStyle = 'white';
    ctx.fillText(text, x, y);
}


drawStroked("37°", 50, 150);

Что делает:

enter image description here

живая скрипка здесь: http://jsfiddle.net/vNWn6/


ЕСЛИ это случается, чтобы выглядеть не так точно при меньших масштабах рендеринга текста, вы всегда можете сделать его большим, но уменьшите его (в приведенном выше случае вы бы сделали ctx.scale(0.25, 0.25))

Ответ 2

Ответ Саймона - хорошее решение, но в некоторых случаях он может иметь смягчающие глюки, особенно с капиталом "M", "V" и "W":

drawStroked("MVW", 50, 150);

http://jsfiddle.net/hwG42/1/

В этом случае лучше всего использовать:

ctx.miterLimit=2;

http://jsfiddle.net/hwG42/3/

Удачи!

Ответ 3

Для гладкой тени вы можете попробовать это

ctx.beginPath();
ctx.fillStyle = 'white';
ctx.font = "bold 9pt Tahoma";
ctx.shadowBlur = 3;
ctx.textAlign = "center";
ctx.shadowColor = "#000000";
ctx.shadowOffs = 0;                 
ctx.fillText('www.ifnotpics.com', 100, 50);        
ctx.closePath();